<?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: Cassio Menezes</title>
    <description>The latest articles on DEV Community by Cassio Menezes (@cassioborgesmenezes).</description>
    <link>https://dev.to/cassioborgesmenezes</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%2F2791168%2F33e8474f-2f8d-4314-9bff-cacab649f756.jpg</url>
      <title>DEV Community: Cassio Menezes</title>
      <link>https://dev.to/cassioborgesmenezes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cassioborgesmenezes"/>
    <language>en</language>
    <item>
      <title>Do You Like Pasta? Your Java Code Might!</title>
      <dc:creator>Cassio Menezes</dc:creator>
      <pubDate>Fri, 21 Mar 2025 12:59:59 +0000</pubDate>
      <link>https://dev.to/cassioborgesmenezes/do-you-like-pasta-your-java-code-might-49jc</link>
      <guid>https://dev.to/cassioborgesmenezes/do-you-like-pasta-your-java-code-might-49jc</guid>
      <description>&lt;p&gt;What if I told you that a fully functional piece of code would be the worst thing that could happen to your project? Consider a single Java class that spans 1276 lines and manages everything from database transactions to user prompts. It would be twisted up like spaghetti. It functions correctly, but when you need to add a feature, fix a bug, or bring on a new developer, things go bananas. This is the real code from a production system, a class named &lt;a href="https://gist.github.com/cassioborgesmenezes/e938db268a431b9928f9fd3308fdc802" rel="noopener noreferrer"&gt;BtnGeraSerrada.java&lt;/a&gt;; it is not an invented horror story. I'm not here to judge; the developer who wrote it did the best they could with the time and resources they had. Instead, let's disassemble this beast to reveal the obscure dangers associated with spaghetti code, as this functional mess now could turn into a maintenance headache tomorrow.&lt;/p&gt;

&lt;p&gt;Spaghetti code enters projects under the false pretense of "&lt;em&gt;getting the job done&lt;/em&gt;" rather than making an announcement with flashing red warnings. A textbook example is the &lt;a href="https://gist.github.com/cassioborgesmenezes/e938db268a431b9928f9fd3308fdc802" rel="noopener noreferrer"&gt;BtnGeraSerrada.java&lt;/a&gt; class I'm presenting, a massive, 1276-line monolith that controls an industrial process to generate sawing operations. It has all the functionality needed to manage transactions, create database entries, validate inputs, and even prompt users in a single location. Though it does not crash, its quality, maintainability, and scalability are all at risk. Let's investigate some of its visible code smells, which are based on fundamental software engineering concepts, and give a sneak peek at improved procedures that we'll discuss in later posts.&lt;/p&gt;

&lt;p&gt;You can find the source code on my Gist &lt;a href="https://gist.github.com/cassioborgesmenezes/e938db268a431b9928f9fd3308fdc802" rel="noopener noreferrer"&gt;https://gist.github.com/cassioborgesmenezes/e938db268a431b9928f9fd3308fdc802&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Smell #1: The God Class
&lt;/h2&gt;

&lt;p&gt;Robert C. Martin highlights the Single Responsibility Principle (SRP) in Clean Code, which states that a class should only have just one reason to change (Martin, 2008). However, &lt;em&gt;BtnGeraSerrada&lt;/em&gt; is a "God Class," capable of handling anything from business logic (&lt;em&gt;criaProducao&lt;/em&gt;) and persistence (&lt;em&gt;NotaHelper.confirmarNotas&lt;/em&gt;) to user interface interactions (&lt;em&gt;contexto.confirmarSimNao&lt;/em&gt;). With over a dozen methods, several of which include more than 100 lines, it is a master of none and a jack-of-all-trades. If you have to make changes to this giant when a database schema or a new user interface requirement arrives, this could have unexpected consequences. In contrast, Martin Fowler suggests in Refactoring that one should break huge classes into simpler, focused units (Fowler, 2018). Consider dividing this into three distinct components, each with a distinct function: &lt;em&gt;SawingOrchestrator&lt;/em&gt;, &lt;em&gt;DataPersister&lt;/em&gt;, and &lt;em&gt;UserPromptService&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Smell #2: Long Methods and Poor Readability
&lt;/h2&gt;

&lt;p&gt;Observe the go method, which is a complex web of nested transactions, loops, and conditionals that spans more than 100 lines. Joshua Bloch promotes simplicity and clarity in Effective Java (Bloch, 2017). Long methods like this are harder to read, debug, or test, particularly if variables like movimentosReference change across scopes. According to the Gang of Four in Design Patterns, a more refined approach would use the Command or Strategy pattern to divide tasks like note confirmation or header construction into distinct, reusable units (Gamma et al., 1994). Shorter methods with descriptive names, such confirmSawingNotes, would tell a story rather than hide it.&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="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BtnGeraSerrada&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ContextoAcao&lt;/span&gt; &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;go&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BtnGeraSerrada&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;go&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ContextoAcao&lt;/span&gt; &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;qtdLinhas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLinhas&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;length&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;qtdLinhas&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mostraErro&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Selecione apenas uma OP"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Registro&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;linhas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLinhas&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;linhas&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;getCampo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ID"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;linhas&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;getCampo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"STATUS"&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;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0"&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;status&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;"0"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mostraErro&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ainda nao foram geradas as chapas!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&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;status&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;"3"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;status&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;"2"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mostraErro&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Essa Serrada ja foi finalizada!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nc"&gt;Confirma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;confirmarSimNao&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Gerar Serrada"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Confirma serragem do bloco?"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&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="nc"&gt;Confirma&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ConfirmaNotaTxManual&lt;/span&gt; &lt;span class="n"&gt;confirma&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;ConfirmaNotaTxManual&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
         &lt;span class="nc"&gt;JapeSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"br.com.sankhya.ctclasse.processando"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TRUE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
         &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;FinalWrapper&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;movimentosReference&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;FinalWrapper&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;

        &lt;span class="cm"&gt;/* Cria Cabeçalho da requisicao do bloco*/&lt;/span&gt;             
                &lt;span class="nc"&gt;SessionHandle&lt;/span&gt; &lt;span class="n"&gt;hnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;hnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JapeSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;   
                &lt;span class="n"&gt;hnd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCanTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TESTE 85"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;hnd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execWithTX&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;JapeSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TXBlock&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nd"&gt;@Override&lt;/span&gt;
                    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doWithTx&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                            &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&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;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
                            &lt;span class="nc"&gt;DynamicVO&lt;/span&gt; &lt;span class="n"&gt;opVO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DynamicVO&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;EntityFacadeFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDWFFacade&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;findEntityByPrimaryKeyAsVO&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SERCAB2"&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;Object&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;});&lt;/span&gt;

                            &lt;span class="n"&gt;m&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;criaReqbloco&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
                            &lt;span class="n"&gt;m&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;criaProducao&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contexto&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="s"&gt;"S"&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="n"&gt;opVO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TERCEIRO"&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
                            &lt;span class="n"&gt;m&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;criaProducao&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TRUE&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
                            &lt;span class="n"&gt;linhas&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;setCampo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OP"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
                            &lt;span class="n"&gt;linhas&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

                            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TESTE 100"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                            &lt;span class="n"&gt;movimentosReference&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setWrapperReference&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&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="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TESTE 105"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;movimentos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;movimentosReference&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWrapperReference&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="nc"&gt;JapeSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hnd&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TESTE 108"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="nc"&gt;NotaHelper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;confirmarNotas&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movimentos&lt;/span&gt;&lt;span class="o"&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;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;movimento&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;movimentos&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;movimento&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="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ZERO&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                            &lt;span class="n"&gt;confirma&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;confirmarNota&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movimento&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                            &lt;span class="n"&gt;bloquearNota&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movimento&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="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;FinalWrapper&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;movimentoBaixa&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;FinalWrapper&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;

                    &lt;span class="cm"&gt;/* Cria Cabeçalho da requisicao do bloco*/&lt;/span&gt;             


                            &lt;span class="n"&gt;hnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JapeSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

                            &lt;span class="n"&gt;hnd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execWithTX&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;JapeSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TXBlock&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                                &lt;span class="nd"&gt;@Override&lt;/span&gt;
                                &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doWithTx&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                                        &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&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;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;

                                        &lt;span class="c1"&gt;//m.add(criaReqbloco(contexto));&lt;/span&gt;
                                        &lt;span class="n"&gt;m&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;criaReqBaixaInsumos&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
                                        &lt;span class="n"&gt;insereCusto&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                                        &lt;span class="c1"&gt;//criaReqEntera(contexto);&lt;/span&gt;
                                        &lt;span class="cm"&gt;/*
                                            m.add(criaReqBaixaInsumos(contexto, id));
                                            m.add(criaProducao(contexto));
                                            linhas[0].setCampo("OP", m.get(3));
                                            linhas[0].save();
                                        */&lt;/span&gt;
                                        &lt;span class="n"&gt;movimentoBaixa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setWrapperReference&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;m&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="nc"&gt;JapeSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hnd&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

                            &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;movimentosBaixa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;movimentosReference&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWrapperReference&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                            &lt;span class="nc"&gt;NotaHelper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;confirmarNotas&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movimentosBaixa&lt;/span&gt;&lt;span class="o"&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;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;movimento&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;movimentosBaixa&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;movimento&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="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ZERO&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                                        &lt;span class="n"&gt;bloquearNota&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movimento&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="n"&gt;atualizaStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;GeraNFT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;JapeSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"br.com.sankhya.ctclasse.processando"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FALSE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;contexto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMensagemRetorno&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fim da operacao!!"&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;h2&gt;
  
  
  Code Smell #3: Tight Coupling and Transaction Chaos
&lt;/h2&gt;

&lt;p&gt;The class has a problem of tight coupling; it is tied to particular implementations by direct calls to &lt;code&gt;EntityFacadeFactory&lt;/code&gt;, &lt;code&gt;JapeSession&lt;/code&gt;, and utility classes like &lt;code&gt;NotaHelper&lt;/code&gt;. You're rewriting half the class if the database layer changes. To make matters worse, there are tons of &lt;code&gt;JapeSession.open()&lt;/code&gt; and &lt;code&gt;execWithTX&lt;/code&gt;sections dispersed about, increasing the risk of partial commits or leaks. As a way to decouple the process logic from the infrastructure, Fowler's Refactoring recommends removing dependencies and putting them into interfaces (such as a &lt;code&gt;TransactionManager&lt;/code&gt;) (Fowler, 2018). This diminishes fragility and complies with SOLID's Dependency Inversion Principle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Smell #4: Error Handling as an Afterthought
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;BtnGeraSerrada&lt;/code&gt;handles errors inconsistently; some methods throw raw &lt;code&gt;Exceptions&lt;/code&gt;, others use &lt;code&gt;contexto.mostraErro()&lt;/code&gt;, and many don't have the right recovery logic or logging. Martin's Clean Code stresses the need for meaningful and purposeful exceptions (Martin, 2008). Instead of merely leaving users with unclear popup warnings, a centralized error-handling approach - perhaps a specific &lt;code&gt;SawingException&lt;/code&gt;with logging - would make failures traceable and recoverable.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Real-World Warning
&lt;/h2&gt;

&lt;p&gt;This code is being used in a live system, so it is not broken. However, there are real costs that come with its complexity: adding functionality feels like defusing a bomb, problems hide in its deepest parts, and onboarding new devs takes weeks. The lesson? Functionality alone isnt enough. As Bloch points out, “Good code is not just about working today — it’s about thriving tomorrow” (Bloch, 2017). We'll refactor this monster in upcoming articles, using principles and patterns to create a sustainable masterpiece. Let that be a lesson in what not to do for the time being.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Beware the God Class&lt;/strong&gt;: A class that reacts inappropriately to SRP and encourages fragility should divide roles to promote resilience and clarity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep It Short and Sweet&lt;/strong&gt;: Use concise, easily understandable language; lengthy approaches obfuscate intent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decouple to Survive&lt;/strong&gt;: Tight coupling to dependencies restricts your flexibility; instead, employ interfaces and inversion of control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handle Errors with Care&lt;/strong&gt;: Blind spots are caused by inconsistent exception handling; consolidate and appropriately log them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quality Is Worthier Than Speed&lt;/strong&gt;: Invest in structure up front as functional spaghetti code now will cost you badly tomorrow.&lt;/p&gt;

&lt;p&gt;Spaghetti code is a debt that accumulates interest, yet it could help you accomplish a deadline. In your projects, have you had to deal with a confusing web like &lt;a href="https://gist.github.com/cassioborgesmenezes/e938db268a431b9928f9fd3308fdc802" rel="noopener noreferrer"&gt;BtnGeraSerrada&lt;/a&gt;? Which poor habits have you observed transforming functional code into headaches for maintenance? Tell me about your experiences solving (or suffering) code quality challenges in the comments below!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Full disclosure: this article was written with the aid of Grok, an AI built by xAI, who helped me organize my ideas and polish the content. The concepts and insights, however, are based on my own daily experiences as a coder.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>softwareengineering</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Why One-Class Java Heroes Are Killing Your Project's Quality</title>
      <dc:creator>Cassio Menezes</dc:creator>
      <pubDate>Wed, 12 Mar 2025 23:05:42 +0000</pubDate>
      <link>https://dev.to/cassioborgesmenezes/why-one-class-java-heroes-are-killing-your-projects-quality-2cph</link>
      <guid>https://dev.to/cassioborgesmenezes/why-one-class-java-heroes-are-killing-your-projects-quality-2cph</guid>
      <description>&lt;p&gt;Have you ever looked at a tangled web of Java code and wondered, “How did it get this complicated?” As Software Engineers, we’ve all dealt with overcrowded classes or brittle workflows. Quality code is not created by chance; it is designed with purpose. What if I told you that delegating tasks and orchestrating workflows might turn your Java projects into maintainable masterpieces? Let’s look at an actual example of Clean Code and Best Practices in action.&lt;/p&gt;

&lt;p&gt;Suppose you’re developing a Java system for handling data — say, a Header containing Items — and save it in a database. The process is triggered by a user event via a Service Provider, and each step must be completed in order: process the data, then store it. It’s easy to put everything into a single class: parsing, validation, and database logic. But here’s where Clean Code and SOLID’s Single Responsibility Principle (SRP) come to the rescue.&lt;/p&gt;

&lt;p&gt;As a Software Engineer, sticking to SRP means providing each class one job. Combining data processing and persistence in a single class violates this concept. Why? Processing logic may change as the input format evolves, and persistence logic changes with database updates — two unrelated reasons to modify the same class. Instead, separate them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HeaderAndItemsProcessor&lt;/code&gt;: Parses and structures the data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DataPersister&lt;/code&gt;: Handles database writes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But how do you integrate these steps into a sequence? Enter the service layer, a &lt;code&gt;DataProcessingService&lt;/code&gt; that orchestrates the workflow. This coordinator receives raw input, passes it to the &lt;code&gt;processor&lt;/code&gt;, and finally passes the final result to the persister. The user event triggers the Service Provider, which simply calls this service. Here’s a simplified version of Java:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataProcessingService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;HeaderAndItemsProcessor&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;DataPersister&lt;/span&gt; &lt;span class="n"&gt;persister&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;DataProcessingService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HeaderAndItemsProcessor&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;DataPersister&lt;/span&gt; &lt;span class="n"&gt;persister&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;processor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persister&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;persister&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processAndPersist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;rawData&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;processor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;processData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rawData&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;persister&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&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;&lt;a href="https://gist.github.com/cassioborgesmenezes/df16cb8c70823351e4c7185d7c54f118" rel="noopener noreferrer"&gt;Details on Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This design is more than just following the rules; it is about quality. Separating concerns makes your code testable (mock the persister!), flexible (switch databases quickly!) and readable (each class tells its own story). This technique aligns with Best Practices for Software Engineers: it eliminates problems, speeds up debugging, and simplifies the onboarding of new team members.&lt;/p&gt;

&lt;p&gt;This isn't just theoretical fluff; it's a practical pattern you can use right away to improve your projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single Responsibility Principle&lt;/strong&gt;: To keep your code modular and maintainable, assign each Java class one specific job&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service Layer&lt;/strong&gt;: Use a coordinator class to coordinate sequential workflows while keeping clarity and control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality Over Haste&lt;/strong&gt;: Investing in Clean Code now saves time and frustration later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practical Java&lt;/strong&gt;: This design is compatible with technologies such as Java 8 and your favorite IDE, making it ideal for everyday programming.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do you believe separating responsibilities like this makes sense in your Java projects? Have you had trouble balancing Clean Code with tight deadlines? Please share your thoughts in the comments—I'd love to know how you approach quality in your Software Engineering journey!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Full disclosure: this article was written with the aid of Grok, an AI built by xAI, who helped me organize my ideas and polish the content. The concepts and insights, however, are based on my own daily experiences as a coder.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>cleancode</category>
      <category>solidprinciples</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Static Factories: When Static Methods Shine (And Why They're Not Always Evil)</title>
      <dc:creator>Cassio Menezes</dc:creator>
      <pubDate>Wed, 05 Mar 2025 12:15:00 +0000</pubDate>
      <link>https://dev.to/cassioborgesmenezes/static-factories-when-static-methods-shine-and-why-theyre-not-always-evil-4gkk</link>
      <guid>https://dev.to/cassioborgesmenezes/static-factories-when-static-methods-shine-and-why-theyre-not-always-evil-4gkk</guid>
      <description>&lt;p&gt;In my recent article (&lt;a href="https://dev.to/cassioborgesmenezes/static-x-oop-1gb7"&gt;Static X OOP&lt;/a&gt;), I suggested that regular classes and interfaces are more effective than utility classes' static methods, particularly when it comes to validation. There are distinctions, though, much like with other software development tasks. I want to look at a situation today where static methods—more especially, static factory methods—can be a useful and sophisticated tool. Inspired by Joshua Bloch's 'Effective Java,' let's see how I utilize them to improve the testability and flexibility of my code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Right Tool
&lt;/h2&gt;

&lt;p&gt;'Effective Java' teaches us to strategically employ static factory methods instead of constructors when applicable. The ability to retrieve subtypes, give descriptive names, and manage instance generation are just a few benefits of these methods. They've been especially helpful to me in managing dependencies like the JapeContext in my work extending ERP platforms.&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;BlockRepository&lt;/span&gt; &lt;span class="nf"&gt;getInstance&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="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BlockRepositoryImpl&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;BlockRepositorySqlExecutorImpl&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;JapeUtils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeWithJape&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Get JapeContext&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error getting JapeContext"&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="c1"&gt;// Handle exception&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;In this case, &lt;code&gt;BlockRepositoryImpl&lt;/code&gt; instances are created using a controlled entry point provided by the &lt;code&gt;getInstance()&lt;/code&gt; method, which functions as a static factory. Using this method enables me to incorporate the intricate reasoning involved in acquiring the &lt;code&gt;JapeContext&lt;/code&gt; into the factory method. Using a &lt;code&gt;BlockRepositorySqlExecutorImpl&lt;/code&gt; and a lambda function, I can postpone retrieving the context until it's truly required. This type of deferred initialization can boost efficiency.&lt;/p&gt;

&lt;p&gt;But the real magic happens when it comes to testing. By using a static factory, I can easily provide a mock &lt;code&gt;JapeContext&lt;/code&gt; during unit tests. For instance, I can create a test-specific &lt;code&gt;getInstance()&lt;/code&gt; method that returns a &lt;code&gt;BlockRepositoryImpl&lt;/code&gt; instance with a mocked &lt;code&gt;BlockRepositorySqlExecutorImpl&lt;/code&gt;. This allows me to isolate the &lt;code&gt;BlockRepositoryImpl&lt;/code&gt; and test its behavior without relying on the actual ERP platform.&lt;/p&gt;

&lt;p&gt;The flexibility of the code is also improved by the use of this pattern. All I have to do is alter the &lt;code&gt;getInstance()&lt;/code&gt; method if I ever need to change how the &lt;code&gt;JapeContext&lt;/code&gt; is retrieved. &lt;code&gt;BlockRepositoryImpl&lt;/code&gt; callers are not impacted. This is a powerful demonstration of the Open/Closed Principle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Static factory methods provide an alternative to static utility classes, which frequently result in rigid and untestable code. They offer a flexible and controlled method for managing dependencies, improving testability, and creating instances. We may create code that is reliable and manageable by using the right tool for the right job.&lt;/p&gt;

&lt;p&gt;Have you used static factory methods in your projects? What insights and experiences do you have? Leave a comment below with your opinions! Let's continue the discussion and learn from each other.&lt;/p&gt;

</description>
      <category>java</category>
      <category>cleancode</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Static x OOP</title>
      <dc:creator>Cassio Menezes</dc:creator>
      <pubDate>Fri, 28 Feb 2025 18:21:17 +0000</pubDate>
      <link>https://dev.to/cassioborgesmenezes/static-x-oop-1gb7</link>
      <guid>https://dev.to/cassioborgesmenezes/static-x-oop-1gb7</guid>
      <description>&lt;p&gt;As Java developers, we are continually aiming to create cleaner, more maintainable code. Recently, while working on a project, I faced a typical problem: how to effectively incorporate validation logic. Should I use a utility class with static methods or a separate class that implements the validation interface? The solution, as I learned, goes beyond convenience, and penetrates the heart of object-oriented ideas.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Question That Sparked It All:
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;“Why use a regular class (implementing a Validator interface) instead of a utility class with static methods for validation in Java?”&lt;/em&gt; This question arose as I was trying to find the best approach for data validation in my application.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Case for Regular Classes (Implementing Interfaces)
&lt;/h2&gt;

&lt;p&gt;Here’s why I leaned towards regular classes, and why you might want to too:&lt;br&gt;
&lt;strong&gt;Object-Oriented Principles (OOP) in Action&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encapsulation: Even stateless validators benefit from encapsulation, bundling related behavior neatly.&lt;/li&gt;
&lt;li&gt;Polymorphism: Interfaces like Validator enable flexible validation strategies and composite validators, something static methods can’t easily replicate.&lt;/li&gt;
&lt;li&gt;Dependency Injection (DI): Regular classes play well with DI, enhancing testability and flexibility — a stark contrast to the rigidity of static methods.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testability That Matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Unit testing becomes a breeze. Mocking and stubbing dependencies in regular classes is straightforward, isolating validation logic for thorough testing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Maintainability and Extensibility for the Long Haul
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Validation logic evolves. Regular classes gracefully accommodate complexity, unlike the potential maintenance headaches of sprawling static utility classes.&lt;/li&gt;
&lt;li&gt;Adding dependencies to external resources, like databases, is easier using regular classes and dependency injection.
Readability and Organization for Clarity:&lt;/li&gt;
&lt;li&gt;Dedicated validator classes enhance code organization, making it easier to understand and maintain.
Adherence to SOLID Principles for Robust Design:&lt;/li&gt;
&lt;li&gt;Regular classes naturally align with the Single Responsibility Principle (SRP) and Open/Closed Principle, fostering a robust and adaptable codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When Static Methods Might Seem Tempting (But Shouldn’t Be)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;While static methods might appear convenient for simple, unchanging validation, they often lead to technical debt eventually.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choosing regular classes (implementing interfaces) over static utility methods leads to a more robust, adaptable, and maintainable solution. It adheres to OOP concepts, improves testability, and supports SOLID principles, all of which are necessary for developing high-quality Java programs.&lt;/p&gt;

&lt;p&gt;What are your thoughts on validation strategies? Have you faced similar dilemmas? Share your experiences and insights in the comments below!&lt;/p&gt;

</description>
      <category>java</category>
      <category>cleancode</category>
      <category>softwaredevelopment</category>
      <category>oop</category>
    </item>
  </channel>
</rss>
