<?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: Antonio Amaral</title>
    <description>The latest articles on DEV Community by Antonio Amaral (@devtonin).</description>
    <link>https://dev.to/devtonin</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%2F743246%2F42d5a53e-1a2c-4941-b072-590a2dd37f5c.jpg</url>
      <title>DEV Community: Antonio Amaral</title>
      <link>https://dev.to/devtonin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devtonin"/>
    <language>en</language>
    <item>
      <title>Refatorando códigos Java como um ninja 🥋</title>
      <dc:creator>Antonio Amaral</dc:creator>
      <pubDate>Mon, 01 Apr 2024 11:06:29 +0000</pubDate>
      <link>https://dev.to/devtonin/refatorando-codigos-java-como-um-ninja-4hol</link>
      <guid>https://dev.to/devtonin/refatorando-codigos-java-como-um-ninja-4hol</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"Qualquer tolo escreve um código que um computador possa enteder. &lt;em&gt;Bons programadores escrevem códigos que os seres humanos podem entender&lt;/em&gt;." (M. Fowler, 1999) &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introdução 🥷🏻
&lt;/h2&gt;

&lt;p&gt;Na minha curta jornada como programador, já me deparei com códigos excelentes. Trechos lindos e fluentes, que até poderiam ser classificados como &lt;em&gt;over-engineering&lt;/em&gt;. Por outro lado, alguns códigos foram de dar dor no coração de qualquer dev. 💔&lt;/p&gt;

&lt;p&gt;A refatoração é muitas vezes subestimada por pessoas non-tech.  Porém, &lt;strong&gt;assim que alguém precisar entender como o código ruim funciona, será necessário tomar alguma atitude a respeito.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A importância da refatoração 🌸
&lt;/h2&gt;

&lt;p&gt;Sempre me interessei pelo tema de refatoração. Re-escrever um código, deixar ele mais &lt;em&gt;clean&lt;/em&gt;, mais fluente.&lt;/p&gt;

&lt;p&gt;E, recentemente, finalizei o livro &lt;em&gt;Refatoração&lt;/em&gt;, por Martin Fowler. Na minha trajetória de livros tech, esse foi o mais especial. O autor passa pelos princípios da refatoração, sendo o core do livro os exemplos de cada anti-pattern passível de mudanças.&lt;/p&gt;

&lt;p&gt;Com os exemplos, Fowler explica como refatorar cada caso.&lt;/p&gt;

&lt;p&gt;Além disso, é notável o foco na &lt;strong&gt;importância dos testes&lt;/strong&gt;. Os testes estão muito atrelados a refatoração. Não existe refatoração sem teste.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Penso nos testes como um detector de bugs para me proteger contra meus próprios erros." (M. Fowler, 1999)  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;O ciclo mencionado, &lt;em&gt;A.K.A&lt;/em&gt; test driven development:
&lt;img src="https://media2.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%2Fmvinqewv5x3p29hkwwjf.png" alt="The TDD flux. Write code -&amp;gt; test -&amp;gt; refactor" width="800" height="393"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stop using else 🍥
&lt;/h2&gt;

&lt;p&gt;Passado o clickbait, o tweet abaixo é uma piada feita pelo grande Felippe Regazio. Esse tema repercurtiu muito na #bolhadev em 2024. Afinal, pode ou não usar else?&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1770307978031161629-748" src="https://platform.twitter.com/embed/Tweet.html?id=1770307978031161629"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1770307978031161629-748');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1770307978031161629&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claro que pode!&lt;/strong&gt; Porém, o uso de else é muitas vezes visto com maus olhos, pois geralmente existe uma lógica mais simples para substituí-lo. Veremos mais no tópico abaixo.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Show me the code!&lt;/em&gt; 😝🍜&lt;/p&gt;

&lt;h2&gt;
  
  
  Substituindo condições aninhadas por &lt;em&gt;Guard Clauses&lt;/em&gt; 🎎
&lt;/h2&gt;

&lt;p&gt;Condições aninhadas muitas vezes dificultam a vida de quem está lendo. Descobrir o fluxo do código a cada execução se torna um desafio. Nesse caso é recomendável a refatoração com &lt;em&gt;Cláusulas de Guarda&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Usaremos os seguintes passos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Selecionar a condição externa a ser substituída e alterá-la para uma cláusula de guarda.&lt;/li&gt;
&lt;li&gt;Testar.&lt;/li&gt;
&lt;li&gt;Se os resultados das cláusulas forem diferentes, seguimos a vida. Se forem iguais, partir para a estratégia de &lt;strong&gt;'Consolidar expressões condicionais'&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Acompanhe o exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Exemplo original - nested conditionals&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getPayAmount&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Result&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isDead&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deadAmount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
   &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSeparated&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
         &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;separatedAmount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isRetired&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retiredAmount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
         &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;normalPayAmount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refatorando...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Refatorando com guard clauses&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getPayAmount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Result&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isDead&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;deadAmount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSeparated&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;separatedAmount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isRetired&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;retiredAmount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;normalPayAmount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os dois modelos de condicionais tem propósitos diferentes. Se ambas as condições fazem parte do &lt;strong&gt;comportamento normal&lt;/strong&gt;, o mais recomendado realmente é o &lt;em&gt;if e else&lt;/em&gt;. Porém, se a condição for &lt;strong&gt;incomum&lt;/strong&gt;, faço a verificação e retorno apenas se for verdadeira, ou seja, &lt;strong&gt;cláusulas de guarda&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra: a classe Collections 🏯 e a &lt;em&gt;Streams API&lt;/em&gt; 🎇
&lt;/h2&gt;

&lt;p&gt;A partir da versão 8 do Java &lt;em&gt;SE&lt;/em&gt;, podemos combinar a classe Collections juntamente a &lt;em&gt;API&lt;/em&gt; de &lt;strong&gt;Streams&lt;/strong&gt;, criando &lt;strong&gt;pipelines de coleção&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media2.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%2Fktq20zoitxdkhhbraj50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fktq20zoitxdkhhbraj50.png" alt="The pipeline operations from Streams API" width="800" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Utilizaremos essas pipes para processar uma série de operações, cada uma &lt;strong&gt;consumindo e gerando uma coleção&lt;/strong&gt;. Ao invés de utilizarmos o &lt;em&gt;for&lt;/em&gt; junto ao &lt;em&gt;if&lt;/em&gt; e &lt;em&gt;else&lt;/em&gt; - o &lt;strong&gt;como&lt;/strong&gt; fazer algo - vamos apenas expressar código de forma declarativa.&lt;/p&gt;

&lt;p&gt;Veja o exemplo abaixo, que percorre um array de names. Caso o valor de &lt;em&gt;i.job&lt;/em&gt; seja 'programmer', ele adiciona o &lt;em&gt;i.name&lt;/em&gt; no array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
Exemplo com for e if
*/&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Employee&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJob&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"programmer"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora utilizando streams: chamamos o &lt;em&gt;.filter()&lt;/em&gt; com nosso predicado, que vai funcionar como o o 'if'. Em seguida, temos nossa ação com o &lt;em&gt;.map()&lt;/em&gt;, que retorna uma stream com o resultado da função aos elementos dela mesma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
Exemplo com streams
*/&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJob&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"programmer"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Employee:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fica evidenciado que a lógica é muito mais fácil de se entender quando escrita através de uma pipeline. 😉&lt;/p&gt;

&lt;p&gt;Além disso, existem outros métodos úteis, como o &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-T-java.util.function.BinaryOperator-" rel="noopener noreferrer"&gt;reduce()&lt;/a&gt; e o &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#sorted--" rel="noopener noreferrer"&gt;sorted()&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações finais ⛩️
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Existem diversos tipos e propósitos de refatoração. Nesse artigo abordei as técnicas que mais vejo carência em códigos legados e pull requests.&lt;/li&gt;
&lt;li&gt;Para mais exemplos, sugiro a leitura do Refatoring por Martin Fowler. Abraços!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Referências 📖
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ler.amazon.com.br/kp/embed?aEditStatssin=B087N8LKYB&amp;amp;preview=newtab&amp;amp;linkCode=kpe&amp;amp;ref_=cm_sw_r_kb_dp_BBJ3AGT4V40ZP8KS078V" rel="noopener noreferrer"&gt;Refatoração (2ª edição) - Martin Fowler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html" rel="noopener noreferrer"&gt;https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oracle.com/br/technical-resources/articles/java/processing-streams-java-se-8.html" rel="noopener noreferrer"&gt;https://www.oracle.com/br/technical-resources/articles/java/processing-streams-java-se-8.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/pt-br/consolidate-conditional-expression" rel="noopener noreferrer"&gt;https://refactoring.guru/pt-br/consolidate-conditional-expression&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>refactoring</category>
      <category>java</category>
      <category>development</category>
      <category>braziliandevs</category>
    </item>
  </channel>
</rss>
