<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://danielwisky.com.br/feed.xml" rel="self" type="application/atom+xml" /><link href="https://danielwisky.com.br/" rel="alternate" type="text/html" hreflang="pt-BR" /><updated>2026-02-26T19:30:07+00:00</updated><id>https://danielwisky.com.br/feed.xml</id><title type="html">Daniel Wisky</title><subtitle>Conteúdos sobre Desenvolvimento e Tecnologia</subtitle><entry><title type="html">Como se Tornar um Programador Excepcional e se Destacar no Mercado de Trabalho</title><link href="https://danielwisky.com.br/2023-08-10-como-se-tornar-programador-destacar-mercado-trabalho/" rel="alternate" type="text/html" title="Como se Tornar um Programador Excepcional e se Destacar no Mercado de Trabalho" /><published>2023-08-10T00:00:00+00:00</published><updated>2023-08-10T00:00:00+00:00</updated><id>https://danielwisky.com.br/como-se-tornar-programador-destacar-mercado-trabalho</id><content type="html" xml:base="https://danielwisky.com.br/2023-08-10-como-se-tornar-programador-destacar-mercado-trabalho/"><![CDATA[<p>O mercado de trabalho para programadores está cada vez mais competitivo e exigente. Para se destacar entre tantos profissionais na área, é necessário ir além do conhecimento técnico básico. Neste artigo, vamos discutir estratégias e dicas para se tornar um programador excepcional e conquistar sucesso no mercado de trabalho.</p>

<ol>
  <li><strong>Busque conhecimento constante:</strong> Não se limite apenas ao conhecimento adquirido na faculdade ou em cursos iniciais. Mantenha-se atualizado sobre as últimas tendências e tecnologias em desenvolvimento de software. Participe de cursos, workshops e conferências, inscreva-se em plataformas de aprendizado online e, acima de tudo, pratique. A dedicação contínua ao aprendizado garantirá o aprimoramento das habilidades técnicas.</li>
  <li><strong>Domine uma ou mais linguagens de programação:</strong> Não se trata apenas de conhecer várias linguagens, mas de dominar profundamente pelo menos uma. Seja Java, Python, JavaScript ou qualquer outra, escolha uma linguagem e explore suas peculiaridades, bibliotecas e frameworks associados. Torne-se um especialista nessa linguagem e você se destacará em qualquer projeto que envolva seu uso.</li>
  <li><strong>Fortaleça suas habilidades de resolução de problemas:</strong> Ser um bom programador envolve a capacidade de resolver problemas complexos de forma eficiente. Aperfeiçoe suas habilidades de resolução de problemas, buscando desafios, enfrentando-os com determinação e experimentando diferentes abordagens. Pratique algoritmos, estruturas de dados e resolução de problemas lógicos. Isso demonstrará sua capacidade de encontrar soluções eficazes.</li>
  <li><strong>Tenha familiaridade com princípios de design e arquitetura de software:</strong> Compreender os princípios de design de software, como o SOLID e o DRY, bem como as melhores práticas de arquitetura de software, é fundamental para se tornar um programador excepcional. Isso ajudará a criar códigos mais estruturados, limpos e fáceis de manter. Esteja familiarizado com os padrões de design populares, como MVC, Observer e Singleton, e saiba quando e como aplicá-los adequadamente.</li>
  <li><strong>Promova o trabalho em equipe:</strong> A habilidade de trabalhar bem em equipe é valorizada em qualquer ambiente de trabalho. Aprenda a colaborar efetivamente com outros desenvolvedores, compartilhando conhecimentos, recebendo feedback de forma construtiva e contribuindo para soluções colaborativas. Ser um membro confiável e cooperativo da equipe aumentará seu valor como profissional.</li>
  <li><strong>Desenvolva habilidades de comunicação:</strong> Um programador excepcional não é apenas hábil tecnicamente, mas também possui ótimas habilidades de comunicação. Explicar conceitos complexos de forma clara, escrever documentação compreensível e saber se comunicar efetivamente com outras equipes e stakeholders é essencial. Investir tempo no desenvolvimento dessas habilidades ajudará a se destacar como um programador completo.</li>
</ol>

<h2 id="conclusão">Conclusão</h2>

<p>Tornar-se um programador excepcional não acontece da noite para o dia, mas requer esforço contínuo e dedicação. Investir em conhecimento constante, dominar uma linguagem de programação, aprimorar habilidades de resolução de problemas, compreender princípios de design e arquitetura de software, promover o trabalho em equipe e desenvolver habilidades de comunicação são estratégias-chave para alcançar o sucesso no mercado de trabalho como programador.</p>

<p>Lembre-se de que, além do conhecimento técnico, a paixão pela programação e a atitude proativa em relação ao aprendizado são qualidades fundamentais para se destacar. Com foco e determinação, você pode se tornar um programador fera e conquistar ótimas oportunidades profissionais.</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Desenvolvimento de Carreira" /><category term="Programação" /><category term="Aprendizado Contínuo" /><summary type="html"><![CDATA[O mercado de trabalho para programadores está cada vez mais competitivo e exigente. Para se destacar entre tantos profissionais na área, é necessário ir além do conhecimento técnico básico. Neste artigo, vamos discutir estratégias e dicas para se tornar um programador excepcional e conquistar sucesso no mercado de trabalho.]]></summary></entry><entry><title type="html">SOLID: Princípio da Inversão da Dependência</title><link href="https://danielwisky.com.br/2023-08-09-principio-inversao-dependencia/" rel="alternate" type="text/html" title="SOLID: Princípio da Inversão da Dependência" /><published>2023-08-09T00:00:00+00:00</published><updated>2023-08-09T00:00:00+00:00</updated><id>https://danielwisky.com.br/principio-inversao-dependencia</id><content type="html" xml:base="https://danielwisky.com.br/2023-08-09-principio-inversao-dependencia/"><![CDATA[<p>O Princípio da Inversão da Dependência (Dependency Inversion Principle - DIP) é um dos princípios fundamentais do SOLID, um conjunto de diretrizes para desenvolvimento de software orientado a objetos. O Princípio da Inversão da Dependência estabelece que módulos de alto nível não devem depender de módulos de baixo nível, e sim de abstrações. Neste artigo, vamos explorar o Princípio da Inversão da Dependência e discutir exemplos práticos de sua implementação.</p>

<p>O Princípio da Inversão da Dependência propõe que as entidades de nível superior não devam depender diretamente das entidades de nível inferior. Em vez disso, ambas devem depender de abstrações. Isso permite que as dependências sejam invertidas, facilitando a extensibilidade, testabilidade e manutenção do código.</p>

<h2 id="exemplos">Exemplos:</h2>

<ol>
  <li>
    <p>Exemplo de violação do Princípio da Inversão da Dependência:</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">Motor</span> <span class="o">{</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">ligar</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Implementação para ligar o motor</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Carro</span> <span class="o">{</span>
     <span class="kd">private</span> <span class="nc">Motor</span> <span class="n">motor</span><span class="o">;</span>
    
     <span class="kd">public</span> <span class="nf">Carro</span><span class="o">()</span> <span class="o">{</span>
         <span class="k">this</span><span class="o">.</span><span class="na">motor</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Motor</span><span class="o">();</span>
     <span class="o">}</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">ligarCarro</span><span class="o">()</span> <span class="o">{</span>
         <span class="n">motor</span><span class="o">.</span><span class="na">ligar</span><span class="o">();</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Nesse exemplo, a classe <code class="language-plaintext highlighter-rouge">Carro</code> possui uma dependência direta da classe <code class="language-plaintext highlighter-rouge">Motor</code>, criando um acoplamento rígido. Qualquer modificação na classe <code class="language-plaintext highlighter-rouge">Motor</code> pode exigir uma adaptação no código da classe <code class="language-plaintext highlighter-rouge">Carro</code>, dificultando a manutenção e extensibilidade.<br /><br /></p>
  </li>
  <li>
    <p>Exemplo de aplicação correta do Princípio da Inversão da Dependência:</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">interface</span> <span class="nc">Motor</span> <span class="o">{</span>
     <span class="kt">void</span> <span class="nf">ligar</span><span class="o">();</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">MotorGasolina</span> <span class="kd">implements</span> <span class="nc">Motor</span> <span class="o">{</span>
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">ligar</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Implementação específica para ligar motor a gasolina</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Carro</span> <span class="o">{</span>
     <span class="kd">private</span> <span class="nc">Motor</span> <span class="n">motor</span><span class="o">;</span>
    
     <span class="kd">public</span> <span class="nf">Carro</span><span class="o">(</span><span class="nc">Motor</span> <span class="n">motor</span><span class="o">)</span> <span class="o">{</span>
         <span class="k">this</span><span class="o">.</span><span class="na">motor</span> <span class="o">=</span> <span class="n">motor</span><span class="o">;</span>
     <span class="o">}</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">ligarCarro</span><span class="o">()</span> <span class="o">{</span>
         <span class="n">motor</span><span class="o">.</span><span class="na">ligar</span><span class="o">();</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Nesse exemplo, aplicamos o Princípio da Inversão da Dependência, introduzindo a interface <code class="language-plaintext highlighter-rouge">Motor</code> como uma abstração. A classe <code class="language-plaintext highlighter-rouge">Carro</code> agora depende da interface <code class="language-plaintext highlighter-rouge">Motor</code> em vez de depender diretamente da classe <code class="language-plaintext highlighter-rouge">MotorGasolina</code>. Isso permite a fácil substituição do motor, caso seja necessário utilizar um motor elétrico ou a diesel, por exemplo, sem modificar o código da classe <code class="language-plaintext highlighter-rouge">Carro</code>.<br /><br /></p>
  </li>
</ol>

<h2 id="conclusão">Conclusão</h2>

<p>O Princípio da Inversão da Dependência é uma diretriz importante para o desenvolvimento de software que visa criar um código mais flexível, extensível e de fácil manutenção. Ao adotar esse princípio, evitamos o acoplamento rígido entre módulos e facilitamos a substituição de dependências.</p>

<p>Ao implementar o Princípio da Inversão da Dependência em Java ou qualquer outra linguagem, é fundamental identificar as dependências diretamente acopladas e criar abstrações adequadas para elas. Utilizar interfaces ou classes abstratas pode ser uma solução eficaz para inverter as dependências. Dessa forma, garantimos um código mais modular, coeso e elegante, proporcionando maior adaptabilidade e reutilização do código.</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Desenvolvimento de Software" /><category term="Java" /><category term="SOLID" /><summary type="html"><![CDATA[O Princípio da Inversão da Dependência (Dependency Inversion Principle - DIP) é um dos princípios fundamentais do SOLID, um conjunto de diretrizes para desenvolvimento de software orientado a objetos. O Princípio da Inversão da Dependência estabelece que módulos de alto nível não devem depender de módulos de baixo nível, e sim de abstrações. Neste artigo, vamos explorar o Princípio da Inversão da Dependência e discutir exemplos práticos de sua implementação.]]></summary></entry><entry><title type="html">SOLID: Princípio da Segregação da Interface</title><link href="https://danielwisky.com.br/2023-08-08-principio-segregacao-interface/" rel="alternate" type="text/html" title="SOLID: Princípio da Segregação da Interface" /><published>2023-08-08T00:00:00+00:00</published><updated>2023-08-08T00:00:00+00:00</updated><id>https://danielwisky.com.br/principio-segregacao-interface</id><content type="html" xml:base="https://danielwisky.com.br/2023-08-08-principio-segregacao-interface/"><![CDATA[<p>O Princípio da Segregação da Interface (Interface Segregation Principle - ISP) é um dos princípios do SOLID, um conjunto de diretrizes para o desenvolvimento de software orientado a objetos. Este princípio estabelece que uma classe não deve ser forçada a depender de interfaces que não utiliza por completo. Neste artigo, iremos explorar o Princípio da Segregação da Interface e apresentar exemplos práticos de implementação em Java.</p>

<p>De acordo com o Princípio da Segregação da Interface, uma interface deve ser coesa e ter apenas o mínimo necessário para seus clientes. As interfaces devem ser segregadas de forma a cada cliente depender apenas dos métodos que precisa utilizar, evitando assim a dependência de funcionalidades desnecessárias.</p>

<h2 id="exemplos">Exemplos:</h2>

<ol>
  <li>
    <p>Exemplo de violação do Princípio da Segregação da Interface:</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">interface</span> <span class="nc">Animal</span> <span class="o">{</span>
     <span class="kt">void</span> <span class="nf">comer</span><span class="o">();</span>
     <span class="kt">void</span> <span class="nf">dormir</span><span class="o">();</span>
     <span class="kt">void</span> <span class="nf">voar</span><span class="o">();</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Pato</span> <span class="kd">implements</span> <span class="nc">Animal</span> <span class="o">{</span>
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">comer</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Pato comendo"</span><span class="o">);</span>
     <span class="o">}</span>
    
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">dormir</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Pato dormindo"</span><span class="o">);</span>
     <span class="o">}</span>
    
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">voar</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Pato voando"</span><span class="o">);</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Cachorro</span> <span class="kd">implements</span> <span class="nc">Animal</span> <span class="o">{</span>
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">comer</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Cachorro comendo"</span><span class="o">);</span>
     <span class="o">}</span>
    
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">dormir</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Cachorro dormindo"</span><span class="o">);</span>
     <span class="o">}</span>
    
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">voar</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Cachorro não voa, implementação desnecessária</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Neste exemplo, a interface <code class="language-plaintext highlighter-rouge">Animal</code> viola o Princípio da Segregação da Interface, pois obriga as classes <code class="language-plaintext highlighter-rouge">Pato</code> e <code class="language-plaintext highlighter-rouge">Cachorro</code> a implementarem o método voar(), sendo que apenas o pato possui essa capacidade. No caso do cachorro, a implementação do método é desnecessária e pode causar confusão.<br /><br /></p>
  </li>
  <li>
    <p>Exemplo de aplicação correta do Princípio da Segregação da Interface:</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">interface</span> <span class="nc">Animal</span> <span class="o">{</span>
     <span class="kt">void</span> <span class="nf">comer</span><span class="o">();</span>
     <span class="kt">void</span> <span class="nf">dormir</span><span class="o">();</span>
 <span class="o">}</span>
    
 <span class="kd">interface</span> <span class="nc">Ave</span> <span class="o">{</span>
     <span class="kt">void</span> <span class="nf">voar</span><span class="o">();</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Pato</span> <span class="kd">implements</span> <span class="nc">Animal</span><span class="o">,</span> <span class="nc">Ave</span> <span class="o">{</span>
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">comer</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Pato comendo"</span><span class="o">);</span>
     <span class="o">}</span>
    
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">dormir</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Pato dormindo"</span><span class="o">);</span>
     <span class="o">}</span>
    
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">voar</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Pato voando"</span><span class="o">);</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Cachorro</span> <span class="kd">implements</span> <span class="nc">Animal</span> <span class="o">{</span>
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">comer</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Cachorro comendo"</span><span class="o">);</span>
     <span class="o">}</span>
    
     <span class="nd">@Override</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">dormir</span><span class="o">()</span> <span class="o">{</span>
         <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Cachorro dormindo"</span><span class="o">);</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Neste exemplo, corrigimos a violação do Princípio da Segregação da Interface ao criar a interface <code class="language-plaintext highlighter-rouge">Ave</code> especificamente para os animais que possuem a capacidade de voar. A classe <code class="language-plaintext highlighter-rouge">Pato</code> agora implementa tanto a interface <code class="language-plaintext highlighter-rouge">Animal</code> quanto a interface <code class="language-plaintext highlighter-rouge">Ave</code>, atendendo apenas aos métodos relevantes para cada caso. A classe <code class="language-plaintext highlighter-rouge">Cachorro</code> depende apenas da interface <code class="language-plaintext highlighter-rouge">Animal</code>, não sendo afetada por funcionalidades desnecessárias.<br /><br /></p>
  </li>
</ol>

<h2 id="conclusão">Conclusão</h2>

<p>O Princípio da Segregação da Interface é fundamental para garantir um código coeso e flexível. Ao aderir a esse princípio, é possível evitar a dependência de funcionalidades desnecessárias, tornando o sistema mais modular e de fácil manutenção. Os exemplos de implementação em Java mostram como corrigir violações do Princípio da Segregação da Interface, criando interfaces mais específicas e reduzindo o acoplamento entre as classes.</p>

<p>Ao aplicar o Princípio da Segregação da Interface em Java ou qualquer outra linguagem de programação, é importante analisar as necessidades de cada classe e criar interfaces que sejam adequadas e coesas para cada cliente. Dessa forma, é possível criar um código mais limpo, de fácil entendimento e que promova a reutilização de código.</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Desenvolvimento de Software" /><category term="Java" /><category term="SOLID" /><summary type="html"><![CDATA[O Princípio da Segregação da Interface (Interface Segregation Principle - ISP) é um dos princípios do SOLID, um conjunto de diretrizes para o desenvolvimento de software orientado a objetos. Este princípio estabelece que uma classe não deve ser forçada a depender de interfaces que não utiliza por completo. Neste artigo, iremos explorar o Princípio da Segregação da Interface e apresentar exemplos práticos de implementação em Java.]]></summary></entry><entry><title type="html">SOLID: Princípio da Substituição de Liskov</title><link href="https://danielwisky.com.br/2023-08-07-principio-substituicao-liskov/" rel="alternate" type="text/html" title="SOLID: Princípio da Substituição de Liskov" /><published>2023-08-07T00:00:00+00:00</published><updated>2023-08-07T00:00:00+00:00</updated><id>https://danielwisky.com.br/principio-substituicao-liskov</id><content type="html" xml:base="https://danielwisky.com.br/2023-08-07-principio-substituicao-liskov/"><![CDATA[<p>O Princípio da Substituição de Liskov (Liskov Substitution Principle - LSP) é um dos princípios do SOLID, um conjunto de diretrizes para o desenvolvimento de software orientado a objetos. Este princípio estabelece que uma classe derivada deve poder substituir sua classe base, mantendo a consistência do sistema. Neste artigo, exploraremos o Princípio da Substituição de Liskov e apresentaremos exemplos de implementação em Java.</p>

<p>Segundo o Princípio da Substituição de Liskov, se uma classe A é um subtipo de uma classe B, então os objetos do tipo B podem ser substituídos pelos objetos do tipo A sem que isso afete o funcionamento correto do sistema. Isso significa que a classe derivada deve ser capaz de atender a todas as pré-condições, pós-condições e invariantes definidos pela classe base.</p>

<h2 id="exemplos">Exemplos:</h2>

<ol>
  <li>
    <p>Exemplo de violação do Princípio de Substituição de Liskov:</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">Retangulo</span> <span class="o">{</span>
     <span class="kd">protected</span> <span class="kt">int</span> <span class="n">largura</span><span class="o">;</span>
     <span class="kd">protected</span> <span class="kt">int</span> <span class="n">altura</span><span class="o">;</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setLargura</span><span class="o">(</span><span class="kt">int</span> <span class="n">largura</span><span class="o">)</span> <span class="o">{</span>
         <span class="k">this</span><span class="o">.</span><span class="na">largura</span> <span class="o">=</span> <span class="n">largura</span><span class="o">;</span>
     <span class="o">}</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setAltura</span><span class="o">(</span><span class="kt">int</span> <span class="n">altura</span><span class="o">)</span> <span class="o">{</span>
         <span class="k">this</span><span class="o">.</span><span class="na">altura</span> <span class="o">=</span> <span class="n">altura</span><span class="o">;</span>
     <span class="o">}</span>
    
     <span class="kd">public</span> <span class="kt">int</span> <span class="nf">calcularArea</span><span class="o">()</span> <span class="o">{</span>
         <span class="k">return</span> <span class="n">largura</span> <span class="o">*</span> <span class="n">altura</span><span class="o">;</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Quadrado</span> <span class="kd">extends</span> <span class="nc">Retangulo</span> <span class="o">{</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setLado</span><span class="o">(</span><span class="kt">int</span> <span class="n">lado</span><span class="o">)</span> <span class="o">{</span>
         <span class="k">this</span><span class="o">.</span><span class="na">largura</span> <span class="o">=</span> <span class="n">lado</span><span class="o">;</span>
         <span class="k">this</span><span class="o">.</span><span class="na">altura</span> <span class="o">=</span> <span class="n">lado</span><span class="o">;</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Neste exemplo, a classe <code class="language-plaintext highlighter-rouge">Quadrado</code> viola o Princípio da Substituição de Liskov, pois impõe restrições adicionais à classe base <code class="language-plaintext highlighter-rouge">Retangulo</code>. Ao modificar apenas um lado do quadrado, o outro lado também é alterado, o que não é esperado em uma hierarquia de classes correta.<br /><br /></p>
  </li>
  <li>
    <p>Exemplo de aplicação correta do Princípio de Substituição de Liskov:</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">Forma</span> <span class="o">{</span>
     <span class="kd">abstract</span> <span class="kt">int</span> <span class="nf">calcularArea</span><span class="o">();</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Retangulo</span> <span class="kd">extends</span> <span class="nc">Forma</span> <span class="o">{</span>
     <span class="kd">protected</span> <span class="kt">int</span> <span class="n">largura</span><span class="o">;</span>
     <span class="kd">protected</span> <span class="kt">int</span> <span class="n">altura</span><span class="o">;</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setLargura</span><span class="o">(</span><span class="kt">int</span> <span class="n">largura</span><span class="o">)</span> <span class="o">{</span>
         <span class="k">this</span><span class="o">.</span><span class="na">largura</span> <span class="o">=</span> <span class="n">largura</span><span class="o">;</span>
     <span class="o">}</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setAltura</span><span class="o">(</span><span class="kt">int</span> <span class="n">altura</span><span class="o">)</span> <span class="o">{</span>
         <span class="k">this</span><span class="o">.</span><span class="na">altura</span> <span class="o">=</span> <span class="n">altura</span><span class="o">;</span>
     <span class="o">}</span>
    
     <span class="nd">@Override</span>
     <span class="kt">int</span> <span class="nf">calcularArea</span><span class="o">()</span> <span class="o">{</span>
         <span class="k">return</span> <span class="n">largura</span> <span class="o">*</span> <span class="n">altura</span><span class="o">;</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Quadrado</span> <span class="kd">extends</span> <span class="nc">Forma</span> <span class="o">{</span>
     <span class="kd">protected</span> <span class="kt">int</span> <span class="n">lado</span><span class="o">;</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setLado</span><span class="o">(</span><span class="kt">int</span> <span class="n">lado</span><span class="o">)</span> <span class="o">{</span>
         <span class="k">this</span><span class="o">.</span><span class="na">lado</span> <span class="o">=</span> <span class="n">lado</span><span class="o">;</span>
     <span class="o">}</span>
    
     <span class="nd">@Override</span>
     <span class="kt">int</span> <span class="nf">calcularArea</span><span class="o">()</span> <span class="o">{</span>
         <span class="k">return</span> <span class="n">lado</span> <span class="o">*</span> <span class="n">lado</span><span class="o">;</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Neste exemplo, corrigimos a violação do Princípio de Substituição de Liskov introduzindo uma classe abstrata <code class="language-plaintext highlighter-rouge">Forma</code>. As classes <code class="language-plaintext highlighter-rouge">Retangulo</code> e <code class="language-plaintext highlighter-rouge">Quadrado</code> agora herdam diretamente dessa classe abstrata, garantindo que todos os métodos estejam corretamente implementados e permitindo a substituição adequada. Cada classe derivada implementa seu próprio método <code class="language-plaintext highlighter-rouge">calcularArea()</code> de acordo com suas características específicas.<br /><br /></p>
  </li>
</ol>

<h2 id="conclusão">Conclusão</h2>

<p>O Princípio da Substituição de Liskov é essencial para garantir a integridade e a consistência em hierarquias de classes. Ao seguir esse princípio, é possível criar classes derivadas que se comportam corretamente, substituindo sua classe base sem que isso afete o funcionamento do sistema. Os exemplos de implementação em Java mostram como evitar violações e aderir corretamente ao Princípio de Substituição de Liskov.</p>

<p>É importante lembrar que adotar esse princípio exige um entendimento adequado do problema e uma análise cuidadosa das relações entre as classes. Ao aplicar o Princípio da Substituição de Liskov em Java ou qualquer outro ambiente de desenvolvimento, é possível criar um código mais coeso, extensível e de fácil manutenção.</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Desenvolvimento de Software" /><category term="Java" /><category term="SOLID" /><summary type="html"><![CDATA[O Princípio da Substituição de Liskov (Liskov Substitution Principle - LSP) é um dos princípios do SOLID, um conjunto de diretrizes para o desenvolvimento de software orientado a objetos. Este princípio estabelece que uma classe derivada deve poder substituir sua classe base, mantendo a consistência do sistema. Neste artigo, exploraremos o Princípio da Substituição de Liskov e apresentaremos exemplos de implementação em Java.]]></summary></entry><entry><title type="html">SOLID: Princípio Aberto-Fechado</title><link href="https://danielwisky.com.br/2023-08-06-principio-aberto-fechado/" rel="alternate" type="text/html" title="SOLID: Princípio Aberto-Fechado" /><published>2023-08-06T00:00:00+00:00</published><updated>2023-08-06T00:00:00+00:00</updated><id>https://danielwisky.com.br/principio-aberto-fechado</id><content type="html" xml:base="https://danielwisky.com.br/2023-08-06-principio-aberto-fechado/"><![CDATA[<p>O Princípio Aberto-Fechado (Open-Closed Principle - OCP) é um dos princípios do SOLID, um conjunto de diretrizes para desenvolvimento de software que visam promover a modularidade, extensibilidade e manutenibilidade do código. O OCP estabelece que as entidades do software (classes, módulos, funções, etc.) devem estar abertas para extensão, mas fechadas para modificação direta. Neste artigo, exploraremos em detalhes o Princípio Aberto-Fechado e forneceremos exemplos de sua aplicação.</p>

<h2 id="o-que-é-o-princípio-aberto-fechado-ocp">O que é o Princípio Aberto-Fechado (OCP)?</h2>

<p>O Princípio Aberto-Fechado declara que as entidades do software devem ser projetadas de maneira a permitir que novos comportamentos sejam adicionados sem a necessidade de modificar o código existente. Isso significa que, ao estender as funcionalidades do sistema, devemos ser capazes de fazer isso através de adição de novas classes ou módulos, em vez de alterar o código existente.</p>

<h2 id="vantagens-do-ocp">Vantagens do OCP:</h2>

<ul>
  <li><strong>Extensibilidade:</strong> O OCP promove a extensibilidade do código, permitindo adicionar novos comportamentos e funcionalidades sem modificar o código existente. Isso facilita a evolução do sistema ao longo do tempo.</li>
  <li><strong>Manutenibilidade:</strong> Como o código existente não é modificado diretamente, há menos riscos de introduzir erros ou efeitos colaterais. Isso torna o código mais previsível e fácil de manter.</li>
  <li><strong>Reutilização:</strong> Com um design aberto para extensão, as classes e módulos podem ser reutilizados em diferentes contextos, promovendo um maior nível de modularidade e compartilhamento de código.</li>
  <li><strong>Testabilidade:</strong> O OCP facilita a realização de testes, já que novas funcionalidades podem ser adicionadas através da criação de novos testes, sem a necessidade de alterar os testes existentes.</li>
</ul>

<h2 id="exemplos">Exemplos:</h2>

<ol>
  <li>
    <p>Exemplo de violação do OCP:</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">Shape</span> <span class="o">{</span>
     <span class="kd">private</span> <span class="nc">String</span> <span class="n">type</span><span class="o">;</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">draw</span><span class="o">()</span> <span class="o">{</span>
         <span class="k">if</span> <span class="o">(</span><span class="n">type</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="s">"circle"</span><span class="o">))</span> <span class="o">{</span>
             <span class="n">drawCircle</span><span class="o">();</span>
         <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">type</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="s">"rectangle"</span><span class="o">))</span> <span class="o">{</span>
             <span class="n">drawRectangle</span><span class="o">();</span>
         <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">type</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="s">"triangle"</span><span class="o">))</span> <span class="o">{</span>
             <span class="n">drawTriangle</span><span class="o">();</span>
         <span class="o">}</span>
     <span class="o">}</span>
    
     <span class="kd">private</span> <span class="kt">void</span> <span class="nf">drawCircle</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Desenhar um círculo</span>
     <span class="o">}</span>
    
     <span class="kd">private</span> <span class="kt">void</span> <span class="nf">drawRectangle</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Desenhar um retângulo</span>
     <span class="o">}</span>
    
     <span class="kd">private</span> <span class="kt">void</span> <span class="nf">drawTriangle</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Desenhar um triângulo</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Neste exemplo, a classe <code class="language-plaintext highlighter-rouge">Shape</code> viola o OCP, pois precisa ser modificada toda vez que um novo tipo de forma (como um hexágono) for adicionado. Isso causa acoplamento excessivo e dificulta a extensibilidade do código.<br /><br /></p>
  </li>
  <li>
    <p>Exemplo de aplicação do OCP:</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">interface</span> <span class="nc">Shape</span> <span class="o">{</span>
     <span class="kt">void</span> <span class="nf">draw</span><span class="o">();</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Circle</span> <span class="kd">implements</span> <span class="nc">Shape</span> <span class="o">{</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">draw</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Desenhar um círculo</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Rectangle</span> <span class="kd">implements</span> <span class="nc">Shape</span> <span class="o">{</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">draw</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Desenhar um retângulo</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">Triangle</span> <span class="kd">implements</span> <span class="nc">Shape</span> <span class="o">{</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">draw</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Desenhar um triângulo</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Neste exemplo, o OCP é aplicado corretamente. As formas são representadas por classes separadas que implementam a interface <code class="language-plaintext highlighter-rouge">Shape</code>. Ao adicionar um novo tipo de forma, basta criar uma nova classe que implementa a interface <code class="language-plaintext highlighter-rouge">Shape</code> e define seu próprio comportamento de desenho. Dessa forma, o código existente não precisa ser modificado, e a extensibilidade é mantida.<br /><br /></p>
  </li>
</ol>

<h2 id="conclusão">Conclusão</h2>

<p>O Princípio Aberto-Fechado (OCP) é um princípio fundamental para o desenvolvimento de software modular e extensível. Ele promove a capacidade de estender o sistema sem modificar o código existente, facilitando a manutenção, reutilização e testabilidade do código. Os exemplos de aplicação mostram como é possível criar um código aderente ao OCP, permitindo a adição de novos comportamentos sem alterar o código já existente.</p>

<p>É importante lembrar que o OCP deve ser aplicado juntamente com outros princípios do SOLID para obter um sistema de software robusto, bem projetado e de fácil manutenção ao longo do tempo.</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Desenvolvimento de Software" /><category term="Java" /><category term="SOLID" /><summary type="html"><![CDATA[O Princípio Aberto-Fechado (Open-Closed Principle - OCP) é um dos princípios do SOLID, um conjunto de diretrizes para desenvolvimento de software que visam promover a modularidade, extensibilidade e manutenibilidade do código. O OCP estabelece que as entidades do software (classes, módulos, funções, etc.) devem estar abertas para extensão, mas fechadas para modificação direta. Neste artigo, exploraremos em detalhes o Princípio Aberto-Fechado e forneceremos exemplos de sua aplicação.]]></summary></entry><entry><title type="html">SOLID: Princípio da Responsabilidade Única</title><link href="https://danielwisky.com.br/2023-08-05-principio-responsabilidade-unica/" rel="alternate" type="text/html" title="SOLID: Princípio da Responsabilidade Única" /><published>2023-08-05T00:00:00+00:00</published><updated>2023-08-05T00:00:00+00:00</updated><id>https://danielwisky.com.br/principio-responsabilidade-unica</id><content type="html" xml:base="https://danielwisky.com.br/2023-08-05-principio-responsabilidade-unica/"><![CDATA[<p>O Princípio da Responsabilidade Única (Single Responsibility Principle - SRP) é um dos princípios do SOLID, um conjunto de princípios de design de software que visam aprimorar a qualidade, a manutenibilidade e a extensibilidade do código. O SRP estabelece que uma classe deve ter apenas uma razão para mudar, ou seja, deve ter uma única responsabilidade.</p>

<p>O SRP propõe dividir as responsabilidades em classes distintas, a fim de manter o código mais coeso, compreensível e fácil de manter. Neste artigo, vamos explorar o SRP em detalhes e fornecer exemplos de implementação em Java.</p>

<h2 id="o-que-é-o-princípio-da-responsabilidade-única-srp">O que é o Princípio da Responsabilidade Única (SRP)?</h2>

<p>O Princípio da Responsabilidade Única declara que uma classe deve ter apenas uma responsabilidade e, portanto, deve ter apenas um motivo para mudar. Cada classe deve ser responsável por fazer uma única tarefa e fazer bem. Isso ajuda a evitar acoplamento excessivo entre classes e torna o código mais modular e testável.</p>

<h2 id="vantagens-do-srp">Vantagens do SRP:</h2>

<ul>
  <li><strong>Coesão:</strong> Uma classe com uma única responsabilidade é mais coesa, pois não está tentando realizar várias tarefas diferentes. Isso ajuda a manter o código mais organizado e fácil de entender.</li>
  <li><strong>Testabilidade:</strong> Classes com uma única responsabilidade são mais fáceis de testar, pois seus comportamentos podem ser testados de forma isolada, sem a interferência de outras responsabilidades.</li>
  <li><strong>Manutenibilidade:</strong> Quando uma mudança ocorre em uma determinada responsabilidade, apenas a classe afetada precisa ser modificada. Isso reduz o risco de introduzir efeitos colaterais em outras partes do sistema.</li>
  <li><strong>Reutilização:</strong> Classes coesas e com uma única responsabilidade são mais propensas a serem reutilizadas em diferentes partes do sistema.</li>
</ul>

<h2 id="exemplos">Exemplos:</h2>

<ol>
  <li>
    <p>Exemplo de classes com múltiplas responsabilidades (violação do SRP):</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">User</span> <span class="o">{</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">register</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Lógica para criar um novo usuário no banco de dados</span>
     <span class="o">}</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">sendEmail</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Lógica para enviar um e-mail de boas-vindas</span>
     <span class="o">}</span>
    
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">generateReport</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Lógica para gerar um relatório do usuário</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Neste exemplo, a classe <code class="language-plaintext highlighter-rouge">User</code> possui três métodos que desempenham diferentes responsabilidades: registrar um usuário, enviar e-mail e gerar um relatório. Essas responsabilidades podem mudar por diferentes motivos, violando o princípio da responsabilidade única.<br /><br /></p>
  </li>
  <li>
    <p>Exemplo de classes com responsabilidades separadas (aplicação do SRP):</p>

    <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">UserManager</span> <span class="o">{</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">registerUser</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Lógica para criar um novo usuário no banco de dados</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">EmailSender</span> <span class="o">{</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">sendWelcomeEmail</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Lógica para enviar um e-mail de boas-vindas</span>
     <span class="o">}</span>
 <span class="o">}</span>
    
 <span class="kd">class</span> <span class="nc">ReportGenerator</span> <span class="o">{</span>
     <span class="kd">public</span> <span class="kt">void</span> <span class="nf">generateUserReport</span><span class="o">()</span> <span class="o">{</span>
         <span class="c1">// Lógica para gerar um relatório do usuário</span>
     <span class="o">}</span>
 <span class="o">}</span>
</code></pre></div>    </div>

    <p>Neste exemplo, as responsabilidades foram divididas em classes distintas. A classe <code class="language-plaintext highlighter-rouge">UserManager</code> é responsável apenas por registrar um usuário, a classe <code class="language-plaintext highlighter-rouge">EmailSender</code> é responsável por enviar e-mails e a classe <code class="language-plaintext highlighter-rouge">ReportGenerator</code> é responsável por gerar relatórios. Cada classe tem apenas uma razão para mudar e uma única responsabilidade, aderindo ao SRP.<br /><br /></p>
  </li>
</ol>

<h2 id="conclusão">Conclusão</h2>

<p>A aplicação do Princípio da Responsabilidade Única (SRP) é fundamental para criar um código bem estruturado, coeso e de fácil manutenção. Ao garantir que uma classe tenha apenas uma responsabilidade, podemos melhorar a legibilidade, a testabilidade e a extensibilidade do código. Os exemplos de implementação em Java ilustram como dividir as responsabilidades em classes distintas, priorizando a coesão e o baixo acoplamento entre elas.</p>

<p>Lembre-se de que o SRP é apenas um dos princípios do SOLID e deve ser aplicado em conjunto com os outros princípios para obter um design de software robusto e escalável.</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Desenvolvimento de Software" /><category term="Java" /><category term="SOLID" /><summary type="html"><![CDATA[O Princípio da Responsabilidade Única (Single Responsibility Principle - SRP) é um dos princípios do SOLID, um conjunto de princípios de design de software que visam aprimorar a qualidade, a manutenibilidade e a extensibilidade do código. O SRP estabelece que uma classe deve ter apenas uma razão para mudar, ou seja, deve ter uma única responsabilidade.]]></summary></entry><entry><title type="html">Sharding no MongoDB: uma forma eficiente de armazenar dados</title><link href="https://danielwisky.com.br/2023-04-10-sharding-no-mongodb/" rel="alternate" type="text/html" title="Sharding no MongoDB: uma forma eficiente de armazenar dados" /><published>2023-04-10T00:00:00+00:00</published><updated>2023-04-10T00:00:00+00:00</updated><id>https://danielwisky.com.br/sharding-no-mongodb</id><content type="html" xml:base="https://danielwisky.com.br/2023-04-10-sharding-no-mongodb/"><![CDATA[<h1 id="olá-vamos-falar-sobre-shards-no-mongodb">Olá! Vamos falar sobre shards no MongoDB!</h1>

<p>Imagine que você tem uma caixa cheia de brinquedos. Quando você quer brincar com um brinquedo específico, é fácil encontrá-lo, porque todos os brinquedos estão em uma única caixa. Mas, e se você tivesse muitos, muitos brinquedos e apenas uma caixa não fosse suficiente para guardá-los todos? Seria difícil encontrar um brinquedo específico naquela bagunça, não é mesmo?</p>

<p>Da mesma forma, quando você está trabalhando com muitos dados em um banco de dados MongoDB, pode ser difícil encontrar o que você precisa se tudo estiver armazenado em um só lugar. É aí que os shards entram em cena.</p>

<p>Shards são como caixas adicionais para armazenar seus dados. Cada shard é um servidor separado que pode armazenar um pedaço dos seus dados. Quando você adiciona um shard, você está basicamente dividindo seus dados em pedaços menores e armazenando-os em servidores diferentes.</p>

<p>Por exemplo, se você tem um banco de dados com informações sobre pessoas de todo o mundo, pode ser uma boa ideia dividir os dados por região geográfica. Você poderia ter um shard para dados da América do Norte, outro para dados da América do Sul, outro para dados da Europa e assim por diante.</p>

<p>Dessa forma, quando você precisar procurar por informações sobre pessoas na América do Sul, você só precisa olhar no shard correspondente, em vez de vasculhar todo o banco de dados. Isso torna as consultas mais rápidas e eficientes.</p>

<p>Mas como o MongoDB sabe qual shard contém os dados que você precisa? É aí que entra outro conceito importante: o sharding key. A sharding key é a chave que o MongoDB usa para determinar em qual shard um determinado pedaço de dados deve ser armazenado.</p>

<p>No nosso exemplo das informações sobre pessoas, a sharding key poderia ser o país de origem. O MongoDB olharia para o país de origem de cada registro e usaria isso para determinar em qual shard o registro deve ser armazenado.</p>

<p>Então, resumindo: shards são como caixas adicionais para armazenar seus dados e dividir suas informações em pedaços menores. O sharding key é a chave usada pelo MongoDB para determinar em qual shard um determinado pedaço de dados deve ser armazenado. E isso torna as consultas mais rápidas e eficientes!</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Banco de Dados" /><category term="MongoDB" /><category term="noSQL" /><category term="Sharding" /><summary type="html"><![CDATA[Olá! Vamos falar sobre shards no MongoDB!]]></summary></entry><entry><title type="html">Introdução ao MapStruct</title><link href="https://danielwisky.com.br/2023-02-22-introducao-ao-mapstruct/" rel="alternate" type="text/html" title="Introdução ao MapStruct" /><published>2023-02-22T00:00:00+00:00</published><updated>2023-02-22T00:00:00+00:00</updated><id>https://danielwisky.com.br/introducao-ao-mapstruct</id><content type="html" xml:base="https://danielwisky.com.br/2023-02-22-introducao-ao-mapstruct/"><![CDATA[<p>MapStruct é uma biblioteca de mapeamento de objetos Java para Java, que gera automaticamente código de mapeamento para converter objetos de um tipo em outro. Com o MapStruct, você não precisa escrever o código de mapeamento manualmente. Em vez disso, o MapStruct o gera automaticamente a partir das anotações definidas nas classes.</p>

<p>Neste artigo, vamos explorar como instalar e usar o MapStruct com alguns exemplos de mapeamento.</p>

<h2 id="instalação-do-mapstruct">Instalação do MapStruct</h2>

<p>O MapStruct é facilmente instalado adicionando sua dependência ao seu arquivo <code class="language-plaintext highlighter-rouge">pom.xml</code> no Maven ou no Gradle.</p>

<p>No Maven, adicione a dependência do MapStruct no bloco <code class="language-plaintext highlighter-rouge">dependencies</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;dependency&gt;
    &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
    &lt;artifactId&gt;mapstruct&lt;/artifactId&gt;
    &lt;version&gt;1.4.2.Final&lt;/version&gt;
&lt;/dependency&gt;
</code></pre></div></div>

<p>No Gradle, adicione a dependência do MapStruct na seção dependencies:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
</code></pre></div></div>

<h2 id="usando-mapstruct">Usando MapStruct</h2>

<p>Para usar o MapStruct, você precisa criar interfaces de mapeamento anotadas com <code class="language-plaintext highlighter-rouge">@Mapper</code>. O MapStruct usa as informações fornecidas nas anotações para gerar o código de mapeamento.</p>

<p>Aqui está um exemplo de como criar uma interface de mapeamento:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@Mapper
public interface CarMapper {
    CarDto carToCarDto(Car car);
}
</code></pre></div></div>

<p>Neste exemplo, estamos mapeando um objeto <code class="language-plaintext highlighter-rouge">Car</code> para um objeto <code class="language-plaintext highlighter-rouge">CarDto</code>. O MapStruct gera automaticamente o código de mapeamento para essa interface. Para usar o mapeamento, você precisa criar uma instância do mapper e chamar o método de mapeamento.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CarMapper carMapper = Mappers.getMapper(CarMapper.class);
CarDto carDto = carMapper.carToCarDto(car);
</code></pre></div></div>

<p>Neste exemplo, estamos criando uma instância do mapper <code class="language-plaintext highlighter-rouge">CarMapper</code> e usando o método <code class="language-plaintext highlighter-rouge">carToCarDto</code> para converter um objeto <code class="language-plaintext highlighter-rouge">Car</code> em um objeto <code class="language-plaintext highlighter-rouge">CarDto</code>.</p>

<h2 id="mapeamento-personalizado">Mapeamento personalizado</h2>

<p>O MapStruct permite que você defina mapeamentos personalizados usando o método <code class="language-plaintext highlighter-rouge">@Mapping</code>. Isso é útil quando o nome da propriedade do objeto de origem não corresponde ao nome da propriedade do objeto de destino.</p>

<p>Aqui está um exemplo de como definir um mapeamento personalizado:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@Mapper
public interface CarMapper {
    @Mapping(source = "numberOfSeats", target = "seatCount")
    CarDto carToCarDto(Car car);
}
</code></pre></div></div>

<p>Neste exemplo, estamos definindo um mapeamento personalizado para a propriedade <code class="language-plaintext highlighter-rouge">numberOfSeats</code> do objeto <code class="language-plaintext highlighter-rouge">Car</code>. O valor dessa propriedade será mapeado para a propriedade <code class="language-plaintext highlighter-rouge">seatCount</code> do objeto <code class="language-plaintext highlighter-rouge">CarDto</code>.</p>

<h2 id="mapeamento-reverso">Mapeamento reverso</h2>

<p>O MapStruct também permite que você defina mapeamentos reversos, que permitem converter objetos de destino em objetos de origem.</p>

<p>Aqui está um exemplo de como definir um mapeamento reverso:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@Mapper
public interface CarMapper {
    CarDto carToCarDto(Car car);

    @InheritInverseConfiguration
    Car carDtoToCar(CarDto carDto);
}
</code></pre></div></div>

<p>Neste exemplo, estamos definindo um mapeamento reverso para converter objetos <code class="language-plaintext highlighter-rouge">CarDto</code> em objetos <code class="language-plaintext highlighter-rouge">Car</code>. Usamos a anotação <code class="language-plaintext highlighter-rouge">@InheritInverseConfiguration</code> para herdar a configuração de mapeamento da função <code class="language-plaintext highlighter-rouge">carToCarDto</code> e, em seguida, definimos o mapeamento inverso para o objeto <code class="language-plaintext highlighter-rouge">CarDto</code>.</p>

<h2 id="mapeamento-de-coleções">Mapeamento de coleções</h2>

<p>O MapStruct também suporta mapeamento de coleções de objetos. Você pode usar as anotações <code class="language-plaintext highlighter-rouge">@MappingTarget</code> e <code class="language-plaintext highlighter-rouge">@IterableMapping</code> para definir o mapeamento de coleções.</p>

<p>Aqui está um exemplo de como definir o mapeamento de uma coleção de objetos:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@Mapper
public interface CarMapper {
CarDto carToCarDto(Car car);

    @IterableMapping(elementTargetType = CarDto.class)
    List&lt;CarDto&gt; carsToCarDtos(List&lt;Car&gt; cars);

    void updateCarFromDto(CarDto carDto, @MappingTarget Car car);
}
</code></pre></div></div>

<p>Neste exemplo, definimos a função <code class="language-plaintext highlighter-rouge">carsToCarDtos</code> para mapear uma lista de objetos <code class="language-plaintext highlighter-rouge">Car</code> em uma lista de objetos <code class="language-plaintext highlighter-rouge">CarDto</code>. Usamos a anotação <code class="language-plaintext highlighter-rouge">@IterableMapping</code> para definir o tipo de objeto de destino como <code class="language-plaintext highlighter-rouge">CarDto</code>.</p>

<p>Também definimos a função <code class="language-plaintext highlighter-rouge">updateCarFromDto</code> para atualizar o objeto <code class="language-plaintext highlighter-rouge">Car</code> a partir de um objeto <code class="language-plaintext highlighter-rouge">CarDto</code>. Usamos a anotação <code class="language-plaintext highlighter-rouge">@MappingTarget</code> para especificar que o objeto <code class="language-plaintext highlighter-rouge">Car</code> é o objeto de destino.</p>

<h2 id="conclusão">Conclusão</h2>

<p>O MapStruct é uma biblioteca de mapeamento de objetos Java para Java que simplifica o processo de mapeamento de objetos. Com o MapStruct, você pode criar interfaces de mapeamento anotadas e deixar o MapStruct gerar automaticamente o código de mapeamento para você. O MapStruct também suporta mapeamento personalizado, mapeamento reverso e mapeamento de coleções de objetos.</p>

<p>Para começar a usar o MapStruct, basta adicioná-lo como uma dependência em seu projeto e criar interfaces de mapeamento anotadas. Com essas interfaces, você pode converter objetos de um tipo em outro sem escrever o código de mapeamento manualmente.</p>

<p>Fonte:
<a href="https://mapstruct.org/" target="\_blank">MapStruct</a>.</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Desenvolvimento de Software" /><category term="Java" /><category term="MapStruct" /><category term="Mapeamento de Objetos" /><summary type="html"><![CDATA[MapStruct é uma biblioteca de mapeamento de objetos Java para Java, que gera automaticamente código de mapeamento para converter objetos de um tipo em outro. Com o MapStruct, você não precisa escrever o código de mapeamento manualmente. Em vez disso, o MapStruct o gera automaticamente a partir das anotações definidas nas classes.]]></summary></entry><entry><title type="html">Introdução ao DynamoDB</title><link href="https://danielwisky.com.br/2023-02-16-introducao-ao-dynamodb/" rel="alternate" type="text/html" title="Introdução ao DynamoDB" /><published>2023-02-16T00:00:00+00:00</published><updated>2023-02-16T00:00:00+00:00</updated><id>https://danielwisky.com.br/introducao-ao-dynamodb</id><content type="html" xml:base="https://danielwisky.com.br/2023-02-16-introducao-ao-dynamodb/"><![CDATA[<p>Amazon DynamoDB é um banco de dados NoSQL gerenciado e escalável fornecido pela Amazon Web Services (AWS). Ele oferece um armazenamento de chave-valor flexível e confiável com escalabilidade automática e alta disponibilidade. O DynamoDB é usado em muitas aplicações que exigem um armazenamento de dados flexível e escalável, como jogos, mídia, comércio eletrônico, publicidade e muito mais.</p>

<p>O DynamoDB foi projetado para ser escalável e altamente disponível, permitindo que ele lide com volumes crescentes de dados e tráfego de usuários. Ele é um banco de dados sem esquema, o que significa que as tabelas do DynamoDB não têm um esquema rígido definido. Em vez disso, as tabelas do DynamoDB são compostas por itens, que são basicamente conjuntos de pares de chave-valor. Isso permite uma grande flexibilidade na modelagem de dados, tornando o DynamoDB uma boa escolha para aplicativos com requisitos de dados complexos e em evolução.</p>

<p>O DynamoDB tem uma API rica que permite operações como criar, ler, atualizar e excluir itens de tabela, além de consultar itens com base em suas chaves e índices secundários. O DynamoDB também possui recursos como transações, streams e triggers que permitem que os aplicativos respondam a eventos de mudança de dados em tempo real.</p>

<h2 id="exemplo-de-implementação-usando-spring-boot-e-java">Exemplo de implementação usando Spring Boot e Java</h2>

<p>Vamos criar um exemplo simples de implementação do DynamoDB usando o Spring Boot e o Java. Nesse exemplo, vamos criar uma tabela simples de usuários e realizar operações básicas de CRUD (criação, leitura, atualização e exclusão) na tabela.</p>

<p>Para começar, precisamos configurar o ambiente de desenvolvimento com o Spring Boot e as bibliotecas necessárias para trabalhar com o DynamoDB. Vamos usar o Spring Initializr para criar um novo projeto do Spring Boot com as dependências necessárias. Podemos criar um novo projeto com as seguintes opções:</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">Tipo de projeto</code>: Maven</li>
  <li><code class="language-plaintext highlighter-rouge">Linguagem</code>: Java</li>
  <li><code class="language-plaintext highlighter-rouge">Versão do Spring Boot</code>: 2.5.6</li>
  <li><code class="language-plaintext highlighter-rouge">Group</code>: com.example</li>
  <li><code class="language-plaintext highlighter-rouge">Artifact</code>: spring-boot-dynamodb-example</li>
  <li><code class="language-plaintext highlighter-rouge">Dependencies</code>: DynamoDB, Spring Web, Spring Data JPA</li>
</ol>

<p>Depois de criar o projeto, podemos adicionar uma nova classe chamada User, que representará um item em nossa tabela do DynamoDB. A classe User deve ter as seguintes propriedades:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@DynamoDBTable</span><span class="o">(</span><span class="n">tableName</span> <span class="o">=</span> <span class="s">"users"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">User</span> <span class="o">{</span>

  <span class="nd">@DynamoDBHashKey</span><span class="o">(</span><span class="n">attributeName</span> <span class="o">=</span> <span class="s">"userId"</span><span class="o">)</span>
  <span class="kd">private</span> <span class="nc">String</span> <span class="n">userId</span><span class="o">;</span>

  <span class="nd">@DynamoDBAttribute</span><span class="o">(</span><span class="n">attributeName</span> <span class="o">=</span> <span class="s">"firstName"</span><span class="o">)</span>
  <span class="kd">private</span> <span class="nc">String</span> <span class="n">firstName</span><span class="o">;</span>

  <span class="nd">@DynamoDBAttribute</span><span class="o">(</span><span class="n">attributeName</span> <span class="o">=</span> <span class="s">"lastName"</span><span class="o">)</span>
  <span class="kd">private</span> <span class="nc">String</span> <span class="n">lastName</span><span class="o">;</span>

  <span class="c1">// getters and setters</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Observe que estamos usando as anotações <code class="language-plaintext highlighter-rouge">@DynamoDBTable</code>, <code class="language-plaintext highlighter-rouge">@DynamoDBHashKey</code> e <code class="language-plaintext highlighter-rouge">@DynamoDBAttribute</code> para mapear nossa classe para uma tabela do DynamoDB. A anotação <code class="language-plaintext highlighter-rouge">@DynamoDBTable</code> é usada para especificar o nome da tabela, enquanto a anotação <code class="language-plaintext highlighter-rouge">@DynamoDBHashKey</code> é usada para especificar a chave primária da tabela. As outras propriedades da classe são mapeadas como atributos da tabela usando a anotação <code class="language-plaintext highlighter-rouge">@DynamoDBAttribute</code>.</p>

<p>Agora podemos criar um repositório para realizar operações CRUD na tabela do DynamoDB. Vamos criar uma nova interface chamada UserRepository com os métodos necessários para realizar operações na tabela. A interface deve estender a interface CrudRepository do Spring Data JPA.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">UserRepository</span> <span class="kd">extends</span> <span class="nc">CrudRepository</span><span class="o">&lt;</span><span class="nc">User</span><span class="o">,</span> <span class="nc">String</span><span class="o">&gt;</span> <span class="o">{</span>

  <span class="nd">@Override</span>
  <span class="nc">Optional</span><span class="o">&lt;</span><span class="nc">User</span><span class="o">&gt;</span> <span class="nf">findById</span><span class="o">(</span><span class="nc">String</span> <span class="n">id</span><span class="o">);</span>

  <span class="nd">@Override</span>
  <span class="kt">void</span> <span class="nf">deleteById</span><span class="o">(</span><span class="nc">String</span> <span class="n">id</span><span class="o">);</span>

<span class="o">}</span>
</code></pre></div></div>

<p>Observe que estamos usando o tipo String para representar a chave primária da tabela do DynamoDB, que é a propriedade userId em nossa classe User.</p>

<p>Agora podemos criar um controlador REST para expor nossos endpoints e realizar operações CRUD na tabela. Vamos criar uma nova classe chamada UserController com os seguintes métodos:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestController</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="s">"/users"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserController</span> <span class="o">{</span>

  <span class="nd">@Autowired</span>
  <span class="kd">private</span> <span class="nc">UserRepository</span> <span class="n">userRepository</span><span class="o">;</span>

  <span class="nd">@PostMapping</span>
  <span class="kd">public</span> <span class="nc">User</span> <span class="nf">createUser</span><span class="o">(</span><span class="nd">@RequestBody</span> <span class="nc">User</span> <span class="n">user</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">userRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">user</span><span class="o">);</span>
  <span class="o">}</span>

  <span class="nd">@GetMapping</span><span class="o">(</span><span class="s">"/{userId}"</span><span class="o">)</span>
  <span class="kd">public</span> <span class="nc">User</span> <span class="nf">getUserById</span><span class="o">(</span><span class="nd">@PathVariable</span> <span class="nc">String</span> <span class="n">userId</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">userRepository</span><span class="o">.</span><span class="na">findById</span><span class="o">(</span><span class="n">userId</span><span class="o">).</span><span class="na">orElse</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span>
  <span class="o">}</span>

  <span class="nd">@PutMapping</span><span class="o">(</span><span class="s">"/{userId}"</span><span class="o">)</span>
  <span class="kd">public</span> <span class="nc">User</span> <span class="nf">updateUser</span><span class="o">(</span><span class="nd">@PathVariable</span> <span class="nc">String</span> <span class="n">userId</span><span class="o">,</span> <span class="nd">@RequestBody</span> <span class="nc">User</span> <span class="n">user</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">user</span><span class="o">.</span><span class="na">setUserId</span><span class="o">(</span><span class="n">userId</span><span class="o">);</span>
    <span class="k">return</span> <span class="n">userRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">user</span><span class="o">);</span>
  <span class="o">}</span>

  <span class="nd">@DeleteMapping</span><span class="o">(</span><span class="s">"/{userId}"</span><span class="o">)</span>
  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">deleteUser</span><span class="o">(</span><span class="nd">@PathVariable</span> <span class="nc">String</span> <span class="n">userId</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">userRepository</span><span class="o">.</span><span class="na">deleteById</span><span class="o">(</span><span class="n">userId</span><span class="o">);</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Observe que estamos usando as anotações do Spring MVC para mapear os endpoints REST para os métodos correspondentes do controlador. Estamos injetando o UserRepository no controlador usando a anotação <code class="language-plaintext highlighter-rouge">@Autowired</code>.</p>

<p>Agora podemos executar nossa aplicação e testar os endpoints REST usando um cliente HTTP. Podemos criar um novo usuário com uma solicitação POST para http://localhost:8080/users com o seguinte corpo:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
    "userId": "1",
    "firstName": "John",
    "lastName": "Doe"
}
</code></pre></div></div>

<p>Podemos recuperar o usuário recém-criado com uma solicitação GET para http://localhost:8080/users/1. Podemos atualizar o usuário com uma solicitação PUT para http://localhost:8080/users/1 com o seguinte corpo:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
    "firstName": "Jane",
    "lastName": "Doe"
}
</code></pre></div></div>

<p>Finalmente, podemos excluir o usuário com uma solicitação DELETE para http://localhost:8080/users/1.</p>

<h2 id="conclusão">Conclusão</h2>

<p>O DynamoDB é um banco de dados NoSQL altamente escalável e gerenciado fornecido pela AWS. Ele oferece um armazenamento de chave-valor flexível e confiável com escalabilidade automática e alta disponibilidade. Neste artigo, criamos um exemplo simples de implementação do DynamoDB usando o Spring Boot e o Java. Criamos uma tabela de usuários e realizamos operações básicas de CRUD na tabela usando um controlador REST e um repositório Spring Data JPA. Com o DynamoDB e o Spring Boot, podemos criar aplicativos altamente escaláveis e flexíveis com facilidade.</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Banco de Dados" /><category term="DynamoDB" /><category term="noSQL" /><category term="Spring Boot" /><category term="Java" /><summary type="html"><![CDATA[Amazon DynamoDB é um banco de dados NoSQL gerenciado e escalável fornecido pela Amazon Web Services (AWS). Ele oferece um armazenamento de chave-valor flexível e confiável com escalabilidade automática e alta disponibilidade. O DynamoDB é usado em muitas aplicações que exigem um armazenamento de dados flexível e escalável, como jogos, mídia, comércio eletrônico, publicidade e muito mais.]]></summary></entry><entry><title type="html">Java: Testes de Mutação</title><link href="https://danielwisky.com.br/2023-01-24-java-testes-de-mutacao/" rel="alternate" type="text/html" title="Java: Testes de Mutação" /><published>2023-01-24T00:00:00+00:00</published><updated>2023-01-24T00:00:00+00:00</updated><id>https://danielwisky.com.br/java-testes-de-mutacao</id><content type="html" xml:base="https://danielwisky.com.br/2023-01-24-java-testes-de-mutacao/"><![CDATA[<h2 id="testes-de-mutação-em-java-uma-técnica-avançada-para-garantir-a-qualidade-do-código">Testes de mutação em Java: uma técnica avançada para garantir a qualidade do código</h2>

<p>Os testes de mutação são uma técnica de teste de software que consiste em modificar intencionalmente o código fonte de uma aplicação e, em seguida, executar testes automatizados para verificar se essas modificações foram detectadas e corrigidas corretamente. Eles são usados para aumentar a confiança no código e na cobertura dos testes, pois ajudam a garantir que as modificações intencionais no código sejam detectadas e corrigidas.</p>

<p>Existem várias ferramentas de teste de mutação disponíveis para Java, como o PIT, o Major, o Mutator e o Javalanche. Essas ferramentas funcionam de maneira semelhante, gerando automaticamente variantes do código fonte da aplicação e, em seguida, executando testes automatizados para detectar se essas variantes foram corrigidas corretamente.</p>

<p>Para usar uma dessas ferramentas, é necessário escrever testes automatizados para a aplicação e configurar a ferramenta de teste de mutação para usar esses testes. Em seguida, a ferramenta gera automaticamente variantes do código fonte e executa os testes automatizados para verificar se essas variantes foram corrigidas corretamente.</p>

<p>Um exemplo de um teste unitário que funciona, mas quebra no teste de mutação, pode ser o seguinte:</p>

<p>Calculator:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Calculator</span> <span class="o">{</span>
  <span class="kd">public</span> <span class="kt">int</span> <span class="nf">add</span><span class="o">(</span><span class="kt">int</span> <span class="n">a</span><span class="o">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="o">;</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>CalculatorTest:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CalculatorTest</span> <span class="o">{</span>
  <span class="nd">@Test</span>
  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">testAdd</span><span class="o">()</span> <span class="o">{</span>
    <span class="nc">Calculator</span> <span class="n">calculator</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Calculator</span><span class="o">();</span>
    <span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="n">calculator</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">);</span>
    <span class="n">assertEquals</span><span class="o">(</span><span class="mi">3</span><span class="o">,</span> <span class="n">result</span><span class="o">);</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Esse teste unitário testa o método <code class="language-plaintext highlighter-rouge">add()</code> da classe <code class="language-plaintext highlighter-rouge">Calculator</code> e verifica se ele retorna o resultado esperado quando é chamado com os valores 1 e 2. Ele passa com sucesso quando é executado normalmente. No entanto, se esse código for submetido a um teste de mutação, ele pode quebrar. Isso ocorre porque a ferramenta de teste de mutação pode modificar o código da seguinte maneira:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Calculator</span> <span class="o">{</span>
  <span class="kd">public</span> <span class="kt">int</span> <span class="nf">add</span><span class="o">(</span><span class="kt">int</span> <span class="n">a</span><span class="o">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">a</span> <span class="o">-</span> <span class="n">b</span><span class="o">;</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Neste caso, a ferramenta de teste de mutação mudou a operação de soma para subtração. O teste unitário ainda passará, mas a função add não estará mais funcionando corretamente.</p>

<p>Para corrigir esse problema, podemos adicionar outros testes para garantir que a função <code class="language-plaintext highlighter-rouge">add</code> funciona corretamente independentemente da operação matemática utilizada.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CalculatorTest</span> <span class="o">{</span>
  <span class="nd">@Test</span>
  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">testAdd</span><span class="o">()</span> <span class="o">{</span>
    <span class="nc">Calculator</span> <span class="n">calculator</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Calculator</span><span class="o">();</span>
    <span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="n">calculator</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">);</span>
    <span class="n">assertEquals</span><span class="o">(</span><span class="mi">3</span><span class="o">,</span> <span class="n">result</span><span class="o">);</span>
  <span class="o">}</span>
  <span class="nd">@Test</span>
  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">testAddNegative</span><span class="o">()</span> <span class="o">{</span>
    <span class="nc">Calculator</span> <span class="n">calculator</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Calculator</span><span class="o">();</span>
    <span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="n">calculator</span><span class="o">.</span><span class="na">add</span><span class="o">(-</span><span class="mi">1</span><span class="o">,</span> <span class="o">-</span><span class="mi">2</span><span class="o">);</span>
    <span class="n">assertEquals</span><span class="o">(-</span><span class="mi">3</span><span class="o">,</span> <span class="n">result</span><span class="o">);</span>
  <span class="o">}</span>
  <span class="nd">@Test</span>
  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">testAddZero</span><span class="o">()</span> <span class="o">{</span>
    <span class="nc">Calculator</span> <span class="n">calculator</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Calculator</span><span class="o">();</span>
    <span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="n">calculator</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="mi">0</span><span class="o">);</span>
    <span class="n">assertEquals</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="n">result</span><span class="o">);</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Dessa forma, se a ferramenta de teste de mutação mudar a operação matemática para subtração, os testes ainda irão detectar a falha e assim garantir que a função <code class="language-plaintext highlighter-rouge">add</code> está funcionando corretamente.</p>

<p>Além disso, existem outras técnicas que podem ser usadas para melhorar a confiabilidade dos testes de mutação. O uso de testes de cobertura de código é uma delas, pois permite verificar se o código está sendo testado adequadamente e se há áreas que precisam ser melhoradas. Além disso, configurar regras de mutação específicas também é uma boa prática, pois permite que você se concentre em áreas específicas do código que podem ser mais propensas a erros. As ferramentas de teste de mutação geralmente oferecem suporte a essas técnicas, tornando-as fáceis de implementar e usar.</p>

<p>É importante lembrar que os testes de mutação não são uma solução mágica para garantir a qualidade do código e não devem ser usados como uma única forma de testar a aplicação. Eles devem ser usados em conjunto com outras técnicas de teste, como testes de unidade, testes de integração e testes de aceitação, para garantir que a aplicação esteja completamente testada e livre de erros.</p>

<p>Um grande abraço e até o próximo post!</p>]]></content><author><name></name></author><category term="Desenvolvimento de Software" /><category term="Java" /><category term="Testes de Mutação" /><category term="Testes Automatizados" /><summary type="html"><![CDATA[Testes de mutação em Java: uma técnica avançada para garantir a qualidade do código]]></summary></entry></feed>