<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Camila Ferreira</title>
    <description>The latest articles on DEV Community by Camila Ferreira (@camilaferreiranas).</description>
    <link>https://dev.to/camilaferreiranas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F800004%2F6d1e8eed-1462-4645-8d59-7c6c7cd35055.jpg</url>
      <title>DEV Community: Camila Ferreira</title>
      <link>https://dev.to/camilaferreiranas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/camilaferreiranas"/>
    <language>en</language>
    <item>
      <title>Padrões de projeto: Builder</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Sat, 23 Nov 2024 14:36:21 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/padroes-de-projeto-builder-4f47</link>
      <guid>https://dev.to/camilaferreiranas/padroes-de-projeto-builder-4f47</guid>
      <description>&lt;p&gt;O padrão de projeto Builder é um padrão criacional que visa abstrair o processo de instânciação de objetos, tornando o sistema independente da forma como os objetos são criados. Ele permite a construção de objetos complexos de maneira incremental, passo a passo, o que é particularmente útil quando um objeto precisa ser montado em várias etapas ou quando as informações necessárias para sua construção são fornecidas em fases distintas.&lt;/p&gt;

&lt;p&gt;Entre suas características principais, podemos destacar:&lt;/p&gt;

&lt;p&gt;Separação de construção e representação: O padrão Builder separa a lógica de construção de um objeto de sua representação final, permitindo que a construção seja feita de forma flexível e modular.&lt;/p&gt;

&lt;p&gt;Facilidade de configuração: Ao utilizar o Builder, é possível criar objetos com diferentes configurações sem a necessidade de mudar o código cliente. Isso proporciona maior flexibilidade no processo de criação.&lt;/p&gt;

&lt;p&gt;Imutabilidade do objeto final: O objeto resultante da construção é geralmente imutável, ou seja, não pode ser alterado após sua criação. Isso evita modificações indesejadas e garante a integridade do objeto.&lt;/p&gt;

&lt;p&gt;Para ilustrar o funcionamento do padrão, imagine a criação de um Produto com diversos atributos, como preço, título, descrição e categoria. Usando o padrão Builder, podemos construir o produto de forma flexível, especificando os diferentes atributos em etapas:&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
public class Produto {&lt;br&gt;
    private Double preco;&lt;br&gt;
    private String titulo;&lt;br&gt;
    private String descricao;&lt;br&gt;
    private String categoria;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private Produto(Builder builder) {
    this.preco = builder.preco;
    this.titulo = builder.titulo;
    this.descricao = builder.descricao;
    this.categoria = builder.categoria;
}

public static class Builder {
    private Double preco;
    private String titulo;
    private String descricao;
    private String categoria;

    public Builder setPreco(Double preco) {
        this.preco = preco;
        return this;
    }

    public Builder setTitulo(String titulo) {
        this.titulo = titulo;
        return this;
    }

    public Builder setDescricao(String descricao) {
        this.descricao = descricao;
        return this;
    }

    public Builder setCategoria(String categoria) {
        this.categoria = categoria;
        return this;
    }

    public Produto build() {
        return new Produto(this);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public class Principal {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void main(String[] args) {
    Produto produto = new Produto.Builder()
            .setPreco(999.9)
            .setTitulo("Smartphone")
            .setCategoria("Celulares")
            .setDescricao("Um celular Android")
            .build();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;Neste exemplo, o Produto é criado utilizando um ProdutoBuilder, permitindo a configuração dos atributos de forma incremental e modular. O uso do padrão Builder torna o processo mais legível e organizado.&lt;/p&gt;

&lt;p&gt;Vantagens do Padrão Builder:&lt;br&gt;
Desacoplamento: O cliente não precisa saber como os objetos são criados, apenas interage com a interface do Builder, o que aumenta a flexibilidade e a coesão do sistema.&lt;br&gt;
Flexibilidade: O Builder permite criar diferentes representações de um objeto de forma fácil e controlada, sem a necessidade de modificar a lógica de construção do objeto.&lt;br&gt;
Manutenção: Como a construção do objeto é separada da sua representação, o código se torna mais modular e fácil de manter.&lt;br&gt;
Esse padrão contribui significativamente para a legibilidade e a escalabilidade do código, especialmente quando se trabalha com objetos complexos que exigem diferentes configurações.&lt;/p&gt;

</description>
      <category>designpatterns</category>
    </item>
    <item>
      <title>Padrões de projeto: Strategy</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Sat, 09 Nov 2024 22:14:25 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/padroes-de-projeto-strategy-1fc</link>
      <guid>https://dev.to/camilaferreiranas/padroes-de-projeto-strategy-1fc</guid>
      <description>&lt;p&gt;Padrões de projeto, ou design patterns, são soluções bem definidas e testadas para resolver problemas comuns no desenvolvimento de software. Eles promovem boas práticas, facilitando a comunicação e o reaproveitamento de soluções entre desenvolvedores e melhorando a manutenibilidade e a eficiência do código.&lt;/p&gt;

&lt;p&gt;O Strategy é um padrão de projeto comportamental, o que significa que ele facilita a comunicação entre objetos e organiza a troca de informações. Com o Strategy, podemos definir uma família de algoritmos, encapsulá-los em classes distintas e torná-los intercambiáveis. Isso torna o padrão ideal quando há várias maneiras de realizar uma tarefa específica, como implementar diferentes formas de pagamento em uma aplicação. Dessa forma, podemos selecionar a estratégia de pagamento sem alterar a estrutura principal da aplicação, respeitando o princípio de aberto/fechado do SOLID e reduzindo o uso de condicionais.&lt;/p&gt;

&lt;p&gt;Exemplo prático em Java&lt;br&gt;
No exemplo abaixo, implementamos um sistema de pagamento que permite ao usuário escolher entre cartão de crédito ou PayPal. A classe ShoppingCart aceita diferentes estratégias de pagamento, aplicando o padrão Strategy para simplificar e organizar a lógica.&lt;/p&gt;

&lt;p&gt;`public interface PaymentStrategy {&lt;br&gt;
    void pay(double amount);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;public class CreditCardPayment implements PaymentStrategy {&lt;br&gt;
    private String cardNumber;&lt;br&gt;
    private String cardHolder;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public CreditCardPayment(String cardNumber, String cardHolder) {
    this.cardNumber = cardNumber;
    this.cardHolder = cardHolder;
}

@Override
public void pay(double amount) {
    System.out.println("Pagando " + amount + " com cartão de crédito.");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public class PayPalPayment implements PaymentStrategy {&lt;br&gt;
    private String email;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public PayPalPayment(String email) {
    this.email = email;
}

@Override
public void pay(double amount) {
    System.out.println("Pagando " + amount + " com PayPal.");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public class ShoppingCart {&lt;br&gt;
    private PaymentStrategy paymentStrategy;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
    this.paymentStrategy = paymentStrategy;
}


public void checkout(double amount) {
    paymentStrategy.pay(amount);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;A interface &lt;strong&gt;PaymentStrategy ** define um método de pagamento genérico.&lt;br&gt;
As classes *&lt;em&gt;CreditCardPayment *&lt;/em&gt; e **PayPalPayment&lt;/strong&gt; implementam essa interface, cada uma encapsulando a lógica de pagamento específica.&lt;br&gt;
A classe &lt;strong&gt;ShoppingCart&lt;/strong&gt; permite definir e trocar a estratégia de pagamento, chamando o método de pagamento da estratégia escolhida.&lt;br&gt;
Esse exemplo ilustra como o padrão Strategy simplifica a adição de novos métodos de pagamento e facilita o entendimento do código, eliminando condicionais e promovendo a reutilização e o princípio de responsabilidade única.&lt;br&gt;
O padrão Strategy é uma poderosa ferramenta para estruturar o código de forma flexível, extensível e fácil de manter. Ele permite adicionar novas estratégias sem alterar o código existente, promovendo a reutilização e facilitando a adaptação do sistema a novos requisitos. No exemplo da aplicação de pagamento, o Strategy simplificou a escolha de métodos de pagamento, organizando as lógicas em classes separadas e deixando o código mais limpo e modular. Esse padrão reduz a necessidade de condicionais, favorece a aplicação dos princípios SOLID e proporciona uma arquitetura que cresce de maneira organizada. Em resumo, o uso do Strategy traz vantagens práticas e contribui para a robustez e escalabilidade do software.&lt;/p&gt;

</description>
      <category>designpatterns</category>
    </item>
    <item>
      <title>Uma introdução a Padrões de projeto</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Sat, 26 Oct 2024 11:54:58 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/uma-introducao-a-padroes-de-projeto-4oda</link>
      <guid>https://dev.to/camilaferreiranas/uma-introducao-a-padroes-de-projeto-4oda</guid>
      <description>&lt;p&gt;Um padrão de projeto descreve um problema recorrente em um contexto específico e a essência de sua solução, de maneira que essa solução possa ser reutilizada em diversas situações sem ser repetitiva. Essa definição foi inicialmente proposta pelo arquiteto Christopher Alexander, cujas ideias influenciaram profundamente a criação dos padrões de projeto orientados a objetos.&lt;/p&gt;

&lt;p&gt;No desenvolvimento de software, os padrões de projeto são soluções reutilizáveis para desafios que surgem com frequência. Eles permitem reaproveitar arquiteturas e designs bem-sucedidos, trazendo mais eficiência e consistência para o processo de desenvolvimento.&lt;/p&gt;

&lt;p&gt;Em geral, os padrões de projeto possuem quatro elementos principais:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Nome do padrão&lt;/strong&gt;: um termo que serve como referência para descrever um problema de design, sua solução e possíveis consequências.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problema&lt;/strong&gt;: define o contexto de aplicação do padrão, descrevendo o problema em si e suas nuances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solução&lt;/strong&gt;: explica os componentes que formam o padrão, seus relacionamentos, responsabilidades e colaborações.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consequências&lt;/strong&gt;: apresenta os resultados esperados e analisa as vantagens e desvantagens de usar o padrão.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Os padrões de projeto são classificados em três categorias principais:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Padrões Criacionais&lt;/strong&gt;: focam na forma de criação de objetos, evitando o uso direto do operador &lt;code&gt;new&lt;/code&gt; e promovendo métodos mais flexíveis e reutilizáveis para a criação. Exemplos incluem &lt;em&gt;Factory Method&lt;/em&gt;, &lt;em&gt;Abstract Factory&lt;/em&gt;, &lt;em&gt;Singleton&lt;/em&gt; e &lt;em&gt;Builder&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Padrões Estruturais&lt;/strong&gt;: abordam a composição de classes e objetos para formar estruturas maiores, organizando relacionamentos de forma a facilitar a reutilização. Exemplos incluem &lt;em&gt;Adapter&lt;/em&gt;, &lt;em&gt;Decorator&lt;/em&gt;, &lt;em&gt;Facade&lt;/em&gt;, &lt;em&gt;Flyweight&lt;/em&gt; e &lt;em&gt;Proxy&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Padrões Comportamentais&lt;/strong&gt;: tratam da comunicação e interação entre objetos e a distribuição de responsabilidades, facilitando o fluxo de dados e ações entre componentes do sistema. Exemplos incluem &lt;em&gt;Chain of Responsibility&lt;/em&gt;, &lt;em&gt;Command&lt;/em&gt;, &lt;em&gt;Observer&lt;/em&gt; e &lt;em&gt;Strategy&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Os padrões de projeto oferecem diversas vantagens, como a possibilidade de reaproveitar soluções testadas, a redução do acoplamento entre componentes, que facilita a manutenção, e a diminuição da duplicação de código. Entretanto, é importante considerar a complexidade do problema antes de adotar um padrão, já que a implementação pode dificultar a legibilidade e eficiência do código se não for aplicada adequadamente. Quando utilizados em problemas que ocorrem repetidamente, os padrões de projeto tornam o design do software mais organizado, robusto e inteligente.&lt;/p&gt;

</description>
      <category>designpatterns</category>
    </item>
    <item>
      <title>Guia básico de Spring Security</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Sat, 26 Oct 2024 11:39:45 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/guia-basico-de-spring-security-5358</link>
      <guid>https://dev.to/camilaferreiranas/guia-basico-de-spring-security-5358</guid>
      <description>&lt;p&gt;O Spring Security é um dos módulos mais robustos e versáteis do framework Spring, projetado para fornecer segurança completa a aplicações Java. Com ele, é possível configurar autenticação, autorização e outras práticas de segurança.&lt;br&gt;
Para entender melhor o Spring Security, vamos explorar os conceitos de autenticação e autorização, além de anotações e práticas comuns, como o uso de tokens para proteger os dados e as interações dos usuários.&lt;br&gt;
A segurança no Spring Security começa com os conceitos de autenticação e autorização, que têm funções distintas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autenticação&lt;/strong&gt;: Esse é o processo de verificação da identidade do usuário. Geralmente, a autenticação exige que o usuário forneça credenciais, como login e senha, que são comparadas com as informações armazenadas em um banco de dados ou outro sistema de autenticação. Assim, o sistema garante que quem está tentando acessar o sistema é quem diz ser. Um exemplo é uma aplicação de estoque, onde um usuário precisa se autenticar antes de visualizar ou cadastrar itens.&lt;br&gt;
&lt;strong&gt;Autorização&lt;/strong&gt;: Após a autenticação, o próximo passo é verificar se o usuário tem permissão para acessar determinados recursos. No exemplo do sistema de estoque, imaginemos que há diferentes papéis, como ADMIN e FUNCIONARIO. Apenas um usuário com o papel ADMIN pode adicionar itens no estoque, enquanto o FUNCIONARIO pode, por exemplo, apenas visualizar itens. Se João, que tem papel FUNCIONARIO, tentar adicionar um item no estoque, essa ação será bloqueada.&lt;/p&gt;

&lt;p&gt;O Spring Security oferece diversas anotações para simplificar a implementação de regras de segurança. Algumas das mais usadas são:&lt;/p&gt;

&lt;p&gt;@PreAuthorize: Realiza a verificação de permissões antes que o método seja executado. Por exemplo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
@PreAuthorize("hasRole('ADMIN')")&lt;br&gt;
public void adicionarItemEstoque() {&lt;br&gt;
    // Código para adicionar item&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
Esse método só será executado se o usuário tiver a role "ADMIN".&lt;/p&gt;

&lt;p&gt;@Secured: Similar ao @PreAuthorize, mas com uma configuração mais direta, @Secured permite especificar quais roles podem acessar determinado método.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@Secured({"ROLE_ADMIN", "ROLE_USER"})&lt;br&gt;
public void acessarMetodoRestrito() {&lt;br&gt;
    // Código para método restrito&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
Neste caso, o método só é acessível para usuários com roles "ROLE_ADMIN" ou "ROLE_USER".&lt;/p&gt;

&lt;p&gt;Em aplicativos modernos, especialmente em APIs REST, o uso de autenticação baseada em tokens é muito comum. O Spring Security facilita a integração com JWT, um padrão seguro e leve que permite a criação de sessões stateless nas quais o token é enviado a cada requisição.&lt;br&gt;
Ao realizar o login, o usuário recebe um token JWT assinado pelo servidor, que é armazenado no cliente e enviado nas próximas requisições. O Spring Security valida o token, verificando as permissões e a autenticidade do usuário antes de permitir o acesso ao recurso solicitado.&lt;/p&gt;

&lt;p&gt;Além da autenticação e autorização, o Spring Security oferece funcionalidades adicionais para proteger ainda mais as aplicações:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proteção Contra Ataques CSRF&lt;/strong&gt;: O Cross-Site Request Forgery (CSRF) é um tipo de ataque que o Spring Security ajuda a mitigar ao gerar tokens específicos para cada sessão do usuário, impedindo que requisições maliciosas sejam aceitas.&lt;br&gt;
&lt;strong&gt;Criptografia de Senhas&lt;/strong&gt;: O Spring Security fornece classes e configurações para criptografar senhas antes de armazená-las, evitando que sejam armazenadas em texto puro, o que é uma prática insegura.&lt;br&gt;
&lt;strong&gt;Filtros de Segurança&lt;/strong&gt;: Utiliza uma cadeia de filtros que intercepta as requisições HTTP para aplicar verificações de segurança, como autenticação de usuários e validação de tokens.&lt;/p&gt;

&lt;p&gt;O Spring Security é uma ferramenta completa e robusta que eleva o nível de segurança das aplicações Java, integrando autenticação, autorização e proteção contra ataques comuns em um único framework. Com recursos como suporte a anotações (@PreAuthorize, @Secured, entre outras), autenticação por tokens JWT e proteção contra CSRF, o Spring Security oferece soluções adequadas para aplicações de qualquer porte. &lt;/p&gt;

</description>
      <category>java</category>
      <category>springsecurity</category>
    </item>
    <item>
      <title>Uma introdução ao Spring Boot</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Sat, 12 Oct 2024 14:59:52 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/uma-introducao-ao-spring-boot-nnl</link>
      <guid>https://dev.to/camilaferreiranas/uma-introducao-ao-spring-boot-nnl</guid>
      <description>&lt;p&gt;Spring Boot é um framework Java projetado para simplificar o desenvolvimento de aplicações baseadas no Spring Framework, eliminando grande parte da configuração manual. Ele visa agilizar o processo de inicialização e configuração dos projetos, fornecendo um ambiente robusto e eficiente para os desenvolvedores.&lt;/p&gt;

&lt;p&gt;Uma das funcionalidades mais notáveis do Spring Boot é a autoconfiguração, que detecta automaticamente as dependências presentes no projeto e configura os componentes necessários sem intervenção explícita. Isso reduz significativamente o tempo de configuração e permite que os desenvolvedores foquem mais na lógica de negócio.&lt;/p&gt;

&lt;p&gt;Outra vantagem importante é o servidor embutido. Ao contrário de soluções como o Java EE, que exige a configuração e gerenciamento de um servidor externo, o Spring Boot já inclui um servidor por padrão, como o Tomcat, permitindo que as aplicações sejam executadas de forma independente, sem a necessidade de configuração manual de um servidor de aplicação.&lt;/p&gt;

&lt;p&gt;Além disso, o Spring Boot fornece uma série de "starter dependencies", que facilitam a configuração inicial de diversos processos. Um exemplo popular é o spring-boot-starter-web, utilizado para criar aplicações web de maneira simplificada.&lt;/p&gt;

&lt;p&gt;O Spring Boot também se destaca pelo uso de anotações que tornam a configuração de projetos ainda mais intuitiva. Algumas das principais anotações são:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@SpringBootApplication&lt;/strong&gt;&lt;br&gt;
A anotação principal do Spring Boot, que combina várias funcionalidades como @Configuration, @EnableAutoConfiguration e @ComponentScan. É usada na classe principal para inicializar a aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@RestController&lt;/strong&gt;&lt;br&gt;
Une @Controller e @ResponseBody, facilitando a criação de controladores REST. Os métodos anotados com @RequestMapping ou equivalentes retornam dados diretamente, em vez de páginas HTML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@RequestMapping&lt;/strong&gt;&lt;br&gt;
Utilizada para mapear requisições HTTP para métodos específicos. Pode ser configurada para diferentes tipos de requisições, como GET, POST, PUT e DELETE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@Autowired&lt;/strong&gt;&lt;br&gt;
Realiza a injeção automática de dependências em classes gerenciadas pelo Spring. No entanto, deve ser usada com cautela para evitar acoplamento excessivo entre diferentes camadas da aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@Service&lt;/strong&gt;&lt;br&gt;
Marca uma classe como um componente de serviço, geralmente usado para encapsular a lógica de negócios da aplicação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@Repository&lt;/strong&gt;&lt;br&gt;
Identifica uma classe como um repositório, que gerencia o acesso aos dados persistidos, geralmente usando JPA ou outra tecnologia de persistência.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@EnableAutoConfiguration&lt;/strong&gt;&lt;br&gt;
Instrui o Spring Boot a configurar automaticamente o contexto da aplicação com base nas dependências presentes no projeto.&lt;/p&gt;

&lt;p&gt;O Spring Boot é uma ferramenta poderosa que simplifica o desenvolvimento de aplicações Java, automatizando a maior parte da configuração e fornecendo um ambiente de execução autossuficiente com servidores embutidos. Suas funcionalidades como autoconfiguração, dependências starter e anotações tornam o processo de desenvolvimento muito mais ágil e eficiente. Dessa forma, o Spring Boot se consolida como uma escolha ideal para desenvolvedores que buscam velocidade, flexibilidade e facilidade de manutenção em suas aplicações Java.&lt;/p&gt;

</description>
      <category>springboot</category>
      <category>java</category>
    </item>
    <item>
      <title>jUnit - Testes unitários em Java</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Sat, 05 Oct 2024 14:25:02 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/junit-testes-unitarios-em-java-iep</link>
      <guid>https://dev.to/camilaferreiranas/junit-testes-unitarios-em-java-iep</guid>
      <description>&lt;p&gt;Para garantir a qualidade e a funcionalidade do nosso código, é essencial certificar-se de que os comportamentos definidos em nossos métodos estão funcionando corretamente. Nesse contexto, entram os testes automatizados, que podem ser classificados em diferentes categorias, como testes unitários, testes de integração e testes de ponta a ponta (End-to-End). Neste artigo, focaremos nos testes unitários.&lt;/p&gt;

&lt;p&gt;Os testes unitários permitem validar unidades específicas do código, como métodos individuais, assegurando que eles se comportem conforme o esperado. No ecossistema Java, o framework mais utilizado para esse propósito é o JUnit.&lt;/p&gt;

&lt;p&gt;O JUnit é um framework de testes de unidade voltado para Java, com o objetivo de garantir a qualidade do código ao validar o funcionamento correto de cada unidade (geralmente métodos). A seguir, veremos um exemplo de uma classe simples, &lt;code&gt;Calculator&lt;/code&gt;, que contém um método sum, responsável por realizar a soma de dois números. Também apresentaremos um teste unitário para esse método, onde replicamos o comportamento desejado para assegurar que o método está correto. Para isso, criamos a classe &lt;code&gt;CalculatorTest&lt;/code&gt;, que contém o teste automatizado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ah640htlg6hh47yu2cu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ah640htlg6hh47yu2cu.png" alt="Classe Java com método sum" width="675" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fki0md8x5lvo4zpxbquhr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fki0md8x5lvo4zpxbquhr.png" alt="Classe de teste do método sum" width="656" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Atualmente, o JUnit está na versão 5, que trouxe várias melhorias e novos recursos. Uma das principais inovações é a modularidade, sendo dividido em três componentes principais:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JUnit Platform:&lt;/strong&gt; Prove suporte para diferentes ambientes de execução.&lt;br&gt;
&lt;strong&gt;JUnit Jupiter:&lt;/strong&gt; Motor de execução para os novos testes JUnit 5.&lt;br&gt;
&lt;strong&gt;JUnit Vintage:&lt;/strong&gt; Fornece suporte retrocompatível para testes escritos em JUnit 3 e JUnit 4.&lt;br&gt;
Além disso, o JUnit 5 introduziu suporte nativo para testes parametrizados e dinâmicos, facilitando a execução de testes com diferentes valores de entrada, bem como suporte para expressões lambda, aproveitando os recursos modernos do Java.&lt;/p&gt;

&lt;p&gt;Os testes unitários desempenham um papel fundamental na manutenção da qualidade e robustez do código, especialmente em projetos de maior escala, onde a complexidade aumenta. O JUnit, sendo o principal framework para testes de unidade em Java, evoluiu significativamente para atender às necessidades modernas de desenvolvimento, oferecendo maior flexibilidade, modularidade e compatibilidade com as novas versões do Java. Com as melhorias trazidas pelo JUnit 5, é possível testar o código de forma mais eficiente, aproveitando funcionalidades avançadas como testes dinâmicos e expressões lambda, ajudando os desenvolvedores a garantirem que seus métodos funcionem corretamente em diferentes cenários.&lt;/p&gt;

</description>
      <category>java</category>
      <category>unittest</category>
      <category>programming</category>
    </item>
    <item>
      <title>Uma breve introdução ao Hibernate</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Sat, 28 Sep 2024 15:14:02 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/uma-breve-introducao-ao-hibernate-52b</link>
      <guid>https://dev.to/camilaferreiranas/uma-breve-introducao-ao-hibernate-52b</guid>
      <description>&lt;p&gt;Hibernate é uma ferramenta ORM (Object-Relational Mapping) amplamente utilizada em projetos Java para mapear objetos de uma aplicação para tabelas de um banco de dados relacional. &lt;br&gt;
O ORM é uma ferramenta que facilita o mapeamento entre as classes de um projeto e as entidades de um banco de dados. &lt;br&gt;
Ao usar um framework como o Hibernate o desenvolvedor consegue se concentrar no desenvolvimento do domínio ao invés de se preocupar com os detalhes da persistência. &lt;/p&gt;

&lt;p&gt;As principais características do Hibernate são: &lt;br&gt;
&lt;strong&gt;1. Transparência no acesso ao dados&lt;/strong&gt;: O Hibernate permite que os desenvolvedores escrevam código Java que se concentra apenas nos objetos e não nos detalhes de persistência&lt;br&gt;
&lt;strong&gt;2. Suporte a transações&lt;/strong&gt;: Hibernate oferece controle transacional integrado, facilitando a integração com diferentes gerenciadores de transações. Isso garante que as operações de leitura e gravação de dados sejam realizadas de uma forma que a integridade dos dados seja garantida. &lt;br&gt;
&lt;strong&gt;3. Controle de herança&lt;/strong&gt;: Hibernate permite mapear herança entre classes de forma flexível para o banco de dados. Existem diferentes estratégias de mapeamento de herança, como:&lt;br&gt;
Single Table Strategy: Uma única tabela para todas as classes da hierarquia.&lt;br&gt;
Joined Table Strategy: Uma tabela para cada classe concreta.&lt;br&gt;
Table per Class Strategy: Uma tabela para cada classe.&lt;br&gt;
&lt;strong&gt;4. Lazy Loading&lt;/strong&gt;: Hibernate suporta o conceito de lazy loading, onde as coleções e associações de dados são carregadas apenas quando necessário, economizando recursos de memória. &lt;br&gt;
&lt;strong&gt;5. Mecanismos de validação&lt;/strong&gt;: O Hibernate se integra com o Bean Validation, permitindo definir regras de validação para os campos de uma entidade diretamente nas anotações da classe. &lt;/p&gt;

&lt;p&gt;O Hibernate é uma das várias implementações da JPA que é uma especificação padrão que define como o ORM deve ser implementado em Java. &lt;br&gt;
Esse framework traz diversos benefícios como a redução de código SQL e JDBC pois o próprio Hibernate gera e executa as consultas automaticamente. Ele também é compatível com uma série de banco de dados relacionais como MySQL, PostgreSQL, MariaDB, etc. O uso de caching e o controle de transações bem definidas ajudam a otimizar a performance da aplicação. &lt;br&gt;
Contudo existem desvantagens no uso de Hibernate como sua curva de aprendizado, embora suas operações mais simples sejam a maioria quando começamos a implementar caching, mapeamento de herança e transações distribuídas podemos enfrentar dificuldades de entendimento num primeiro momento. A abstração oferecida pelo Hibernate também pode adicionar overhead em certas situações, especialmente quando consultas altamente otimizadas são necessárias. &lt;/p&gt;

&lt;p&gt;Abaixo podemos ver um exemplo com uma classe &lt;em&gt;Produto&lt;/em&gt; e logo abaixo uma explicação sobre algumas das annotations do JPA que são implementadas pelo Hibernate. &lt;/p&gt;

&lt;p&gt;`@Entity&lt;br&gt;
@Table(name = "produto")&lt;br&gt;
public class Produto {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private BigInteger id;

@Column(name = "nome_produto", nullable = false)
private String nome;

@Column(name = "descricao_produto")
private String descricao;

@Column(name = "preco_produto", nullable = false)
private BigDecimal preco;

// Getter e Setters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}`&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;@Entity&lt;br&gt;
A annotation @Entity indica que a classe Produto é uma entidade JPA. Isso significa que ela será mapeada para uma tabela no banco de dados. Cada instância da classe Produto corresponde a uma linha dessa tabela.&lt;br&gt;
A classe deve ter um campo com a annotation &lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt; para indicar o identificador único (chave primária) da entidade no banco de dados.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;@Table(name = "produto")&lt;br&gt;
A annotation @Table especifica o nome da tabela no banco de dados à qual essa entidade será mapeada. No exemplo, name = "produto" define que a tabela associada à entidade Produto será chamada "produto". Se a annotation @Table não fosse fornecida, o nome da tabela seria, por padrão, o nome da classe.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt;&lt;br&gt;
A annotation &lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt; é utilizada para marcar o campo id como a chave primária da entidade. No banco de dados, esse campo será utilizado como o identificador único de cada instância da entidade Produto.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;@GeneratedValue(strategy = GenerationType.SEQUENCE)&lt;br&gt;
A annotation @GeneratedValue indica que o valor do campo id será gerado automaticamente. A propriedade strategy = GenerationType.SEQUENCE especifica que o Hibernate deve usar uma sequência para gerar os valores da chave primária no banco de dados.&lt;br&gt;
Existem outras estratégias para gerar chaves primárias, como:&lt;br&gt;
AUTO: Delega a escolha da estratégia ao provedor de persistência (no caso, o Hibernate).&lt;br&gt;
IDENTITY: Usa uma coluna de identidade do banco de dados, que gera o valor automaticamente durante a inserção.&lt;br&gt;
TABLE: Usa uma tabela específica para armazenar as chaves primárias.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;@Column(name = "nome_produto", nullable = false)&lt;br&gt;
A annotation @Column mapeia o campo nome da classe para a coluna correspondente no banco de dados. No exemplo, a coluna será chamada "nome_produto".&lt;br&gt;
O parâmetro nullable = false indica que essa coluna não pode ser nula no banco de dados. Ou seja, é obrigatório que o campo nome tenha um valor.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O Hibernate é uma ferramenta poderosa e flexível para manipulação de dados em aplicações Java, eliminando a necessidade de escrever SQL manualmente. Ele facilita o desenvolvimento de aplicações complexas ao abstrair o mapeamento entre objetos e tabelas do banco de dados e, ao ser compatível com a especificação JPA, oferece uma API padronizada, com a possibilidade de usar funcionalidades avançadas.&lt;/p&gt;

</description>
      <category>java</category>
      <category>hibernate</category>
      <category>sql</category>
      <category>jpa</category>
    </item>
    <item>
      <title>SOLID - Boas práticas para POO</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Sun, 28 Apr 2024 15:26:35 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/solid-boas-praticas-para-poo-lhj</link>
      <guid>https://dev.to/camilaferreiranas/solid-boas-praticas-para-poo-lhj</guid>
      <description>&lt;p&gt;Criar sistemas com qualidade pode ser um desafio. Quando utilizamos linguagens com suporte à Programação Orientada a Objetos (POO), podemos desenvolver sistemas que aplicam conceitos como herança, abstração e polimorfismo, reduzindo a duplicação de código e outros problemas que podem gerar débitos técnicos.&lt;/p&gt;

&lt;p&gt;O SOLID é um acrônimo que representa princípios que facilitam a manutenção de sistemas. Esses princípios auxiliam o desenvolvedor a criar código limpo e com responsabilidades bem definidas em cada componente, ampliando os benefícios já existentes na POO.&lt;/p&gt;

&lt;p&gt;O primeiro princípio é o da Responsabilidade Única (S - Single Responsibility Principle). Neste princípio, uma classe ou método deve ter apenas uma responsabilidade ou motivo para mudar. Por exemplo, um método que salva um item no banco de dados, valida os dados e realiza processamento desses dados antes de salvar viola esse princípio. Seguindo a Responsabilidade Única, o ideal é ter três métodos distintos: um para salvar os dados, outro para validar e um terceiro para processar os dados. Isso garante métodos mais concisos, reduzindo a chance de introduzir bugs ao modificá-los.&lt;/p&gt;

&lt;p&gt;O segundo princípio é o Aberto-Fechado (O - Open-Closed Principle). Aqui, um componente deve estar aberto para extensão, mas fechado para modificação. Quando precisamos adicionar ou alterar um comportamento, devemos estender o componente em vez de modificar o código original. Por exemplo, ao calcular impostos, se um novo tipo de imposto é necessário, devemos estender a classe existente em vez de modificar seu código. Isso ajuda a evitar bugs no código existente e a controlar o crescimento do código.&lt;/p&gt;

&lt;p&gt;O terceiro princípio é a Substituição de Liskov. Ele estabelece que uma classe filha deve poder substituir sua classe pai sem alterar o comportamento esperado. Isso é fundamental para garantir o uso efetivo do polimorfismo, mantendo uma relação clara entre a classe pai e a classe filha, mesmo com comportamentos internos diferentes.&lt;/p&gt;

&lt;p&gt;O quarto princípio é a Segregação de Interfaces. Aqui, uma classe não deve ser forçada a implementar métodos que não utiliza. Por exemplo, se uma interface possui dez métodos, mas uma classe precisa implementar apenas três, é aconselhável criar uma nova interface contendo apenas esses três métodos. Isso evita métodos não utilizados em uma classe e simplifica a manutenção.&lt;/p&gt;

&lt;p&gt;O quinto princípio é a Inversão de Dependência, que sugere depender de abstrações em vez de implementações concretas. Isso reduz o acoplamento entre classes, facilitando a substituição e extensão do código.&lt;/p&gt;

&lt;p&gt;O SOLID oferece uma maneira eficiente de criar código limpo, fácil de manter e menos propenso a bugs durante as alterações. Compreender bem esses princípios auxilia os desenvolvedores a criar software de qualidade.&lt;/p&gt;

&lt;p&gt;Referências: &lt;br&gt;
&lt;a href="https://www.freecodecamp.org/portuguese/news/os-principios-solid-da-programacao-orientada-a-objetos-explicados-em-bom-portugues/"&gt;https://www.freecodecamp.org/portuguese/news/os-principios-solid-da-programacao-orientada-a-objetos-explicados-em-bom-portugues/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/desenvolvendo-com-paixao/o-que-%C3%A9-solid-o-guia-completo-para-voc%C3%AA-entender-os-5-princ%C3%ADpios-da-poo-2b937b3fc530"&gt;https://medium.com/desenvolvendo-com-paixao/o-que-%C3%A9-solid-o-guia-completo-para-voc%C3%AA-entender-os-5-princ%C3%ADpios-da-poo-2b937b3fc530&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Uma introdução à Arquitetura orientada a eventos</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Sun, 21 Apr 2024 15:27:03 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/uma-introducao-a-arquitetura-orientada-a-eventos-1h3l</link>
      <guid>https://dev.to/camilaferreiranas/uma-introducao-a-arquitetura-orientada-a-eventos-1h3l</guid>
      <description>&lt;p&gt;Com a popularização da arquitetura de microserviços, outras opções para desenvolver um sistema complexo com alta disponibilidade ganham mais destaque; uma dessas formas é a arquitetura orientada a eventos.&lt;/p&gt;

&lt;p&gt;A arquitetura de microserviços é baseada em baixo acoplamento de serviços, em que cada serviço tem seu próprio processo. Um sistema típico de microserviços possui diversos serviços independentes que se comunicam para realizar ações no sistema. Existem duas formas de comunicação entre microserviços: command e query. Com o Command, um serviço "solicita" que outro serviço realize uma ação, podendo ter uma resposta ou não. Já no Query, um serviço "solicita" a outro serviço algum dado e sempre há uma resposta contendo esse dado. Contudo, essa forma de se comunicar pode criar problemas de desempenho, alto acoplamento e problemas de escalabilidade.&lt;/p&gt;

&lt;p&gt;Nesse tipo de cenário, a arquitetura orientada a eventos pode auxiliar no desenvolvimento do sistema. Uma arquitetura orientada por eventos usa eventos para acionamento e comunicação entre serviços desacoplados e é comum em aplicações modernas criadas com microsserviços. Um evento é a indicação de que algo aconteceu no sistema e não há uma resposta para o evento.&lt;/p&gt;

&lt;p&gt;A arquitetura orientada a eventos possui três componentes principais: o Producer, que cria o evento; o Channel, responsável por distribuir os eventos para as partes interessadas; e o Consumer, que recebe o evento pelo Channel e processa aquele evento.&lt;/p&gt;

&lt;p&gt;Existem diversas vantagens na arquitetura orientada a eventos. Como mencionado anteriormente, existiam alguns problemas na forma tradicional de comunicação na arquitetura de microserviços; já na arquitetura orientada a eventos, esses problemas são minimizados. Por exemplo, os problemas de desempenho são reduzidos porque a arquitetura orientada a eventos é assíncrona, o canal não espera uma resposta do consumidor. No problema de acoplamento entre serviços, isso também é eliminado, pois o produtor envia o evento para o canal, que por sua vez envia os eventos para tópicos ou filas, e nenhum dos dois (Producer e Channel) tem ideia de quem está consumindo aquele evento. Quanto à escalabilidade, pode-se adicionar quantos consumidores forem necessários para processar os eventos do canal.&lt;/p&gt;

&lt;p&gt;Comumente, a arquitetura orientada a eventos está ligada ao padrão Pub/Sub, que é um serviço de mensagens assíncrono e escalonável que separa os serviços que produzem mensagens dos serviços que as processam. Esse padrão possui como componentes o Publisher, que atua como o Producer, o Broker que atua como o Channel e o Subscriber que atua como o Consumer. A principal diferença entre eles é que a arquitetura orientada a eventos descreve toda a arquitetura do sistema, enquanto o Pub/Sub é um padrão de envio de mensagens usado pelo sistema.&lt;/p&gt;

&lt;p&gt;Geralmente, a arquitetura orientada a eventos trata-se de serviços, mas os eventos podem ser utilizados como armazenamento de dados. O Event Sourcing e o CQRS oferecem um padrão para armazenar dados como eventos. Nos bancos de dados tradicionais, não podemos armazenar todas as alterações que foram feitas naquele dado, já no Event Sourcing podemos capturar todas as alterações feitas naquele dado como eventos; nesse padrão, não há atualizações ou remoções de dados, apenas inserções. No CQRS, temos a separação dos comandos de atualização/inserção/remoção das consultas; assim, temos uma base de dados para inserir/atualizar/remover dados e outra base de dados para consultar os dados. Isso é utilizado para melhorar o desempenho e a simplicidade do sistema. As bases de dados são sincronizadas usando um mecanismo central de sincronização.&lt;/p&gt;

&lt;p&gt;Embora apresente diversas vantagens, utilizar a arquitetura orientada a eventos pode ser complexo e não é recomendado para equipes que não possuem maturidade na compreensão de arquitetura de software, pois isso pode causar complexidade desnecessária para o sistema. Outro caso em que a arquitetura orientada a eventos não é recomendada é em casos em que o sistema requer comunicação síncrona entre serviços.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referências&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/pt/event-driven-architecture/"&gt;https://aws.amazon.com/pt/event-driven-architecture/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://cloud.google.com/pubsub/docs/overview?hl=pt-br#:%7E:text=O%20Pub%2FSub%20%C3%A9%20um,com%20lat%C3%AAncias%20de%20100%20milissegundos"&gt;https://cloud.google.com/pubsub/docs/overview?hl=pt-br#:~:text=O%20Pub%2FSub%20%C3%A9%20um,com%20lat%C3%AAncias%20de%20100%20milissegundos&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>softwarearchiteture</category>
      <category>programming</category>
    </item>
    <item>
      <title>Como voltar a estudar sobre boas práticas está mudando a forma que eu desenvolvo (e alguns motivos para você estudar também)</title>
      <dc:creator>Camila Ferreira</dc:creator>
      <pubDate>Tue, 14 Nov 2023 21:20:53 +0000</pubDate>
      <link>https://dev.to/camilaferreiranas/como-voltar-a-estudar-sobre-boas-praticas-esta-mudando-a-forma-que-eu-desenvolvo-e-alguns-motivos-para-voce-estudar-tambem-3gbb</link>
      <guid>https://dev.to/camilaferreiranas/como-voltar-a-estudar-sobre-boas-praticas-esta-mudando-a-forma-que-eu-desenvolvo-e-alguns-motivos-para-voce-estudar-tambem-3gbb</guid>
      <description>&lt;p&gt;Projetos com escopo grande e prazo apertado são aqueles momentos em que você aprende muito sobre soft skills, comunicação, autoconhecimento e outras coisas, mas e a parte técnica? É muito difícil se manter atualizado e até seguir boas práticas que você já conhece muito bem quando o prazo é apertado. E quando o dev sai daquele projeto em que tudo é pra ontem para um projeto com um prazo um pouco mais tranquilo e um espaço maior para boas práticas? &lt;br&gt;
É exatamente isso que está acontecendo comigo há alguns meses. Nas primeiras semanas você tenta entender aquele código que parece diferente daquelas gambiarras que você costumava fazer na pressa, algumas coisas na hora da code review não passam, tem que criar testes unitários antes de subir. &lt;br&gt;
Nas primeiras semanas a sindrome do impostor bate muito forte, bem pesado, mas depois de 2-3 reviews que passam direto você respira e pensa "estou me acostumando" mas você começa a perceber uma coisa muito interessante, existe um oceano azul de coisas que são essenciais para um desenvolvedor aprender, e que eu iria além em dizer, que são fundamentos e nem são mencionadas em faculdade. &lt;br&gt;
Todo mundo sabe que orientação a objetos é importante saber um pouco, protocolos de comunicação também, entender um pouquinho de HTML, CSS e Javascript é básico mas e boas práticas? Uma coisa tão importante que pode até definir o destino de um projeto e pouco se fala disso, vemos uma enxurrada de vídeos sobre como criar um To Do com React.js ou uma API Rest de produtos com Spring Boot mas e conteúdos para iniciantes para que eles desde o início comecem a pensar em boas práticas como um processo essencial do desenvolvimento de software? Bom, mas o post não é exatamente sobre isso, esse post é pra falar o porquê você precisa começar a aprender boas práticas e por isso eu vou voltar a história que estava contando sobre meu novo trabalho. &lt;br&gt;
Estar em contato com pessoas que entendem bastante sobre boas práticas, que estão constantemente falando sobre separação de responsabilidades, SOLID, Design Patterns, testes unitários e outras coisas está sendo essencial para mim porque eu estou correndo atrás para entender mais sobre essas coisas que já tinha estudado em um tempo atrás mas parei. &lt;br&gt;
E por que deveríamos estudar boas práticas independente da senioridade? Código limpo é mais barato. Se você já participou de um projeto com prazos apertados provavelmente em algum momento muitas funcionalidades voltaram com alguns bugs e isso é normal, quando estamos desenvolvendo com pressa não contamos com casos que podem acontecer no dia a dia e isso acaba gerando algum bug, e quando você precisa alterar algo naquele código cheio de gambiarras demora um tempo considerável. &lt;br&gt;
Seguir boas práticas sempre será útil, especialmente nesses casos, pois escrever código com qualidade evita retrabalho e bugs que podem afetar a experiência do usuário. &lt;br&gt;
Atualmente tenho focado em entender mais sobre boas práticas sabendo de sua importância. Código limpo, implementar princípios SOLID, criar testes unitários, saber alguns design patterns não são exigências sem sentido mas sim uma forma de definir o sucesso ou o fracasso de um projeto.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>solidprinciples</category>
      <category>cleancode</category>
    </item>
  </channel>
</rss>
