<?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: Felix Coutinho</title>
    <description>The latest articles on DEV Community by Felix Coutinho (@felixcoutinho).</description>
    <link>https://dev.to/felixcoutinho</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%2F800828%2Fb939db69-9696-43f2-a9e2-767c962e956c.jpg</url>
      <title>DEV Community: Felix Coutinho</title>
      <link>https://dev.to/felixcoutinho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/felixcoutinho"/>
    <language>en</language>
    <item>
      <title>Mentorship is a Marathon</title>
      <dc:creator>Felix Coutinho</dc:creator>
      <pubDate>Fri, 04 Oct 2024 17:49:44 +0000</pubDate>
      <link>https://dev.to/felixcoutinho/mentorship-is-a-marathon-2lnf</link>
      <guid>https://dev.to/felixcoutinho/mentorship-is-a-marathon-2lnf</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Mentorship is a long-term journey, not a quick fix.&lt;/p&gt;

&lt;p&gt;There’s a common misconception that getting a mentorship can provide instant career results. Having mentored software developers informally for over a decade and formally for the last two or three years, I’ve seen many of these people seeking guidance with unrealistic expectations and impossible timelines. More on timelines than expectations. Often, they hope for quick results after just a couple of sessions. But, this way of doing things really misses the point of what mentorship is all about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Heads-up&lt;/strong&gt; — I’m not a professional mentor. What follows is simply my conclusion about mentoring software developers, engineers, and architects, along with some insights from this process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spot the Difference: Mentorship vs. Consulting
&lt;/h2&gt;

&lt;p&gt;Before going into effective mentorship, we need to understand the differences between mentoring and consulting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consulting&lt;/strong&gt; is focused on solving specific problems, sometimes projects, or providing expert advice for immediate issues. It's usually short-term and handles specific issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mentorship&lt;/strong&gt;, on the other hand, is about making a long-term commitment to help someone grow and develop, and guiding their career over time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Troubleshooting, debugging, and fixing a bug requires consultancy, not mentorship.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Effective Mentorship
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Not about quick problem-solving
&lt;/h3&gt;

&lt;p&gt;If you need a quick solution to an urgent problem, you’re looking for a consultant, not a mentor. Mentorship is about long-term growth, not quick fixes. It’s about developing skills, mindsets, and approaches that will serve you throughout your career.&lt;/p&gt;

&lt;p&gt;For example, if you’re preparing for an interview and need help in advance, that’s more suited for a mock interview session. Sure, your mentor can help with interview prep, but that’s just one aspect of a broader mentoring process.&lt;/p&gt;

&lt;p&gt;Similarly, troubleshooting or understanding a codebase requires consultancy (or maybe a freelancer), not mentorship.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time is essential
&lt;/h3&gt;

&lt;p&gt;The most successful mentorship relationships I’ve been part of have lasted 24-48 months. It’s rare to see meaningful results in under six months. This timeframe allows for real growth, the application of new skills, and the development of new habits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comprehensive Process
&lt;/h3&gt;

&lt;p&gt;An effective mentorship process involves but is not limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regular 1:1 sessions&lt;/li&gt;
&lt;li&gt;In-depth discussions&lt;/li&gt;
&lt;li&gt;Practical exercises (coding, system design)&lt;/li&gt;
&lt;li&gt;Mock presentations (design sessions, interviews)&lt;/li&gt;
&lt;li&gt;Assessments&lt;/li&gt;
&lt;li&gt;Ongoing feedback and adjustments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Commitment is Required
&lt;/h3&gt;

&lt;p&gt;I typically recommend a 6-12 month initial period to my formal mentees. After this, we reassess their progress and decide together whether to continue for another 6-12 months.&lt;/p&gt;

&lt;h3&gt;
  
  
  It’s Personalized
&lt;/h3&gt;

&lt;p&gt;Each person is unique. Each career is unique. Each mentorship should be tailored to an individual’s goals, strengths, and areas for improvement. What works for you may not work for someone else. I recognize this and you need to recognize this for the sake of your success.&lt;/p&gt;

&lt;h3&gt;
  
  
  Independent Learning
&lt;/h3&gt;

&lt;p&gt;In technical fields, I often recommend books or resources for my mentees to study. This self-paced learning is crucial for deep understanding, allowing the mentee to exercise their brains on deeper topics instead of relying on shallow reads or quick videos.&lt;/p&gt;

&lt;p&gt;As a side note, I’m a slow reader myself. It can take weeks or months to thoroughly go through a book—and that’s okay! Day by day, book by book, topic by topic, a mentee will get closer to their next level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proximity Can Enhance the Experience
&lt;/h3&gt;

&lt;p&gt;In my experience mentoring developers within the workplace, I’ve seen tremendous success. With a paced schedule (biweekly, monthly, or bi-monthly), I can sometimes observe daily progress. This proximity allows frequent interactions and immediate feedback. I recommend people who want to become mentors start mentoring junior workmates first. &lt;/p&gt;

&lt;h3&gt;
  
  
  Remote Mentoring Has Its Challenges
&lt;/h3&gt;

&lt;p&gt;Mentoring across different countries or continents presents its own challenges. Without structured exercises and regular check-ins, it’s harder to assess progress. This requires extra effort in planning and communication from both mentor and mentee. We can expect even longer mentoring periods here.&lt;/p&gt;

&lt;h3&gt;
  
  
  It Can Last a Lifetime
&lt;/h3&gt;

&lt;p&gt;Some of my most pleasant and successful mentorship experiences have spanned a decade or more. I have mentees (now I call them friends) who started with me 10 years ago, and we’re still in regular contact through sessions and chats even though they live far from me. It’s incredibly fulfilling to witness their progress and achievements in professional and personal life over such a long period.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Marathon
&lt;/h2&gt;

&lt;p&gt;Remember, professional growth is a long-distance race, not a sprint. If you’re searching for mentorship, you need to be prepared to invest your time and effort not just in sessions, but in your learning between the 1:1 sessions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Professional growth is a long-distance race, not a sprint.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The metaphor of a marathon fits mentorship well. Like a marathon runner, a mentee must be ready for the long journey. Progress may feel slow at times, but consistent effort over time leads to significant growth. The mentor cannot run for you but he/she can support you. The mentor, like a running coach, provides guidance and support, but the hard work of learning and growth is on you.&lt;/p&gt;

&lt;p&gt;Just as a marathon runner doesn’t become a champion in two sessions of training, software developers don’t transform their careers in a couple of mentoring sessions. Again, it requires persistence, dedication, and guidance.&lt;/p&gt;

&lt;h2&gt;
  
  
  One More Metaphor
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"No matter how great the talent or efforts, some things just take time. You can’t produce a baby in one month by getting nine women pregnant." - Warren Buffett  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Although &lt;a href="https://www.goodreads.com/quotes/476827-no-matter-how-great-the-talent-or-efforts-some-things" rel="noopener noreferrer"&gt;Buffett is the author of this phrase&lt;/a&gt;, it may have been inspired by a classic Software Project Management book called &lt;em&gt;&lt;a href="https://www.goodreads.com/book/show/13629.The_Mythical_Man_Month" rel="noopener noreferrer"&gt;The Mythical Man Month&lt;/a&gt;&lt;/em&gt; (originally published in 1975, and still worth reading).  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s the original:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The bearing of a child takes nine months, no matter how many women are assigned." (&lt;em&gt;The Mythical Man Month&lt;/em&gt;, p. 17)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The point is, some tasks are, as the author would say, “sequentially constrained.” They require a certain amount of time, no matter how many people work on them. This is especially true for career development. You can accelerate it by finding a mentor and breaking inertia, but your career takes time to mature and see results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hey!&lt;/strong&gt; If you liked this read and want to embark on the marathon of growing your career in software development, you can learn more about my mentorship approach and get started by visiting my &lt;a href="https://mentors.to/felixcoutinho" rel="noopener noreferrer"&gt;MentorCruise profile&lt;/a&gt; or by sending me a connection request here on &lt;a href="https://www.linkedin.com/in/felixcoutinho/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mentorship</category>
      <category>career</category>
      <category>development</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>[PT-BR] Entendendo o Spring Framework na Prática</title>
      <dc:creator>Felix Coutinho</dc:creator>
      <pubDate>Mon, 21 Aug 2023 15:39:20 +0000</pubDate>
      <link>https://dev.to/felixcoutinho/pt-br-entendendo-o-spring-framework-na-pratica-51hg</link>
      <guid>https://dev.to/felixcoutinho/pt-br-entendendo-o-spring-framework-na-pratica-51hg</guid>
      <description>&lt;p&gt;No meetup realizado pelo JavaxCE em abril de 2023, tive a incrível oportunidade de compartilhar minha paixão pelo Spring, meu framework favorito, com todos os participantes.&lt;/p&gt;

&lt;p&gt;Se você é um entusiasta de Java ou está ansioso para aprofundar seus conhecimentos sobre o Spring, não pode perder a gravação do evento, agora disponível no YouTube. Acompanhe todas as informações e insights valiosos que compartilhei durante minha palestra.&lt;/p&gt;

&lt;p&gt;🎥 Assista à gravação do meetup:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/h5QDk2V4mrQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Minha palestra se concentrou em fornecer tanto uma visão conceitual quanto prática para auxiliar os desenvolvedores a compreenderem integralmente o ecossistema do Spring Framework. Durante a sessão, mergulhamos nas complexidades das Rest APIs utilizando o Spring Web, exploramos as melhores práticas para acesso a dados com Spring Data e desvendamos os segredos de desenvolvimento ágil com Spring Boot. Ao longo da jornada, abordei os pilares fundamentais do Spring, como a Inversão de Controle, Injeção de Dependência, gerenciamento de preocupações transversais, adoção de convenções sobre configuração e muito mais.&lt;/p&gt;

&lt;p&gt;📦 Confira o repositório de código que desenvolvemos ao vivo: &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/FelixCoutinho"&gt;
        FelixCoutinho
      &lt;/a&gt; / &lt;a href="https://github.com/FelixCoutinho/meetup-javaxce-ecommerce-backend"&gt;
        meetup-javaxce-ecommerce-backend
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Esse repositório contém a prova de conceito com alguns conceitos discutidos durante a apresentação de Abril de 2023 no JavaxCE.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
meetup-javaxce-ecommerce-backend&lt;/h1&gt;
&lt;p&gt;Esse repositório contém a prova de conceito com alguns conceitos discutidos durante a apresentação de Abril de 2023 no JavaxCE.&lt;/p&gt;
&lt;h2&gt;
Gravação no YouTube&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=h5QDk2V4mrQ" rel="nofollow"&gt;https://www.youtube.com/watch?v=h5QDk2V4mrQ&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Slides da aprensentação&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://speakerdeck.com/felixcoutinho/entendendo-o-spring-framework-na-pratica" rel="nofollow"&gt;https://speakerdeck.com/felixcoutinho/entendendo-o-spring-framework-na-pratica&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/FelixCoutinho/meetup-javaxce-ecommerce-backend"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Para aqueles que desejam uma recapitulação visual, disponibilizei os slides da apresentação.&lt;/p&gt;

&lt;p&gt;🖥️ Slides da apresentação:&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://speakerdeck.com/felixcoutinho/entendendo-o-spring-framework-na-pratica" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--xPeZ0_Rz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://files.speakerdeck.com/presentations/1d89457c76da405d8ecf76d43e2b372f/slide_0.jpg%3F25259802" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://speakerdeck.com/felixcoutinho/entendendo-o-spring-framework-na-pratica" rel="noopener noreferrer" class="c-link"&gt;
          Entendendo o Spring Framework na Prática - Speaker Deck
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          A palestra fornece um guia conceitual e prático para ajudar os desenvolvedores a entenderem o Spring Framework, cobrindo seus principais conceitos e componentes. Durante a sessão, serão explorados Rest APIs com Spring Web, acesso a dados com Spring Data e como desenvolver aplicativos rapidamente com Spring Boot, enquanto abordamos os fundamentos do Spring, tais como Inversão de Controle, Injeção de Dependência, Cross-cutting concerns, Convenção sobre Configuração e muito mais.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--hTR4_2pe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://d1eu30co0ohy4w.cloudfront.net/assets/favicon-bdd5839d46040a50edf189174e6f7aacc8abb3aaecd56a4711cf00d820883f47.png" width="512" height="512"&gt;
        speakerdeck.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Obrigado a todos que participaram e espero que essa experiência tenha contribuído para uma melhor compreensão e entusiasmo em relação ao Spring Framework. Fiquem à vontade para compartilhar seus comentários e sugestões aqui.&lt;/p&gt;

</description>
      <category>spring</category>
      <category>java</category>
      <category>springboot</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>You should stop using Spring @Autowired</title>
      <dc:creator>Felix Coutinho</dc:creator>
      <pubDate>Wed, 26 Apr 2023 17:18:14 +0000</pubDate>
      <link>https://dev.to/felixcoutinho/you-should-stop-using-spring-autowired-p8i</link>
      <guid>https://dev.to/felixcoutinho/you-should-stop-using-spring-autowired-p8i</guid>
      <description>&lt;p&gt;Or "Why you shouldn't use Field Injection when using Spring".&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;*&lt;em&gt;TL;DR *&lt;/em&gt;&lt;br&gt;
Injecting beans directly into fields using &lt;em&gt;@Autowired&lt;/em&gt; makes your dependencies "hidden" and encourages bad design. Use constructor-based injection instead.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;It is very likely that you have already seen an &lt;em&gt;@Autowired&lt;/em&gt; annotation when coding in a Java/Spring application. However, what most of my friends developers don't know is that auto-wiring is one of the most commonly seen anti-patterns in codebases that use the Spring IoC/DI Framework.&lt;/p&gt;

&lt;p&gt;Just to refresh your memory here is a short example of what I'm talking about.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt; &lt;span class="c1"&gt;// Field Injection&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;It may seem like a simple and pragmatic way to do Dependency Injection, right? But the consequences of this can turn your codebase slowly (or fast) into spaghetti.&lt;/p&gt;

&lt;p&gt;But why do developers keep choosing this approach? Possibly because it's easy to use and provides an out-of-the-box experience when a developer needs to inject a dependency into a class. However, similar to any other bad practice, this is very easy to replicate across the rest of the codebase, and usually people will never argue why that code design choice was made. And what's the result of using @Autowired? Your code will suffer from &lt;strong&gt;coupling&lt;/strong&gt;, a &lt;strong&gt;bad test experience&lt;/strong&gt;, &lt;strong&gt;hidden dependencies&lt;/strong&gt;, and others.&lt;/p&gt;

&lt;p&gt;In my perspective, the absence of comprehension of the underlying mechanics of a system can potentially result in disastrous codebases. This is applicable to the usage of '@Autowired' when using Spring. Without a thorough grasp of crucial concepts such as Inversion of Control and Dependency Injection, developers are more likely to make errors and become ensnared in this pitfall.&lt;/p&gt;

&lt;p&gt;To gain a better understanding of code design best practices, it's important for developers and architects to review key concepts and explore different approaches to Dependency Injection with Spring. By doing so, we can evaluate which method is optimal for our needs, and potentially uncover the drawbacks of using @Autowired as a dependency injection strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependency Injection with Spring
&lt;/h2&gt;

&lt;p&gt;Dependency Injection is a crucial pattern in software development and is present in production-ready frameworks like Spring. It promotes loose coupling between classes, improves testability, and facilitates modularity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisbsk57cl4hua2o2ulm4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisbsk57cl4hua2o2ulm4.jpeg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are basically three ways to do Dependency Injection using the Spring Framework:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Field Injection&lt;/strong&gt; uses reflection to set the values of private attributes/fields. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setter Injection&lt;/strong&gt; uses public setters to set the value of the attributes/fields. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constructor Injection&lt;/strong&gt; happens at the time of creating the object itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Field Injection
&lt;/h3&gt;

&lt;p&gt;Field injection can be achieved using Spring by adding the @Autowired annotation to a class field. And what does @Autowired do? @Autowired is an annotation provided by Spring that allows the automatic wiring of the dependency. When applied to a field, method, or constructor, Spring will try to find a suitable dependency of the required type and inject it into the target class.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;@Autowired&lt;/em&gt; alone is not the root of all evil. The key aspect is WHERE you are using &lt;em&gt;@Autowired&lt;/em&gt;. Most of the time, developers use it at the field/attribute level. Using it at the setter method can reduce the damage, but not eliminate all of it at all.&lt;/p&gt;

&lt;p&gt;But why @Autowired is so bad? Basically, @Autowired violates some good code design principles.&lt;/p&gt;

&lt;h4&gt;
  
  
  Dependency Inversion (D from SOLID)
&lt;/h4&gt;

&lt;p&gt;If you want to use your class outside the application container, for example for unit testing, you are forced to use a Spring container to instantiate your class as there is no other possible way (but reflection) to set the @Autowired fields. &lt;/p&gt;

&lt;p&gt;When using field-based dependency injection with @Autowired, the class is inherently hiding these dependencies from the outside world. In other words, no point of injection exists.&lt;/p&gt;

&lt;p&gt;Below you can see an example of this scenario.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

   &lt;span class="nd"&gt;@Autowired&lt;/span&gt; 
   &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Multiplier&lt;/span&gt; &lt;span class="n"&gt;multiplier&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;int&lt;/span&gt; &lt;span class="nf"&gt;add&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;a&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;b&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&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;int&lt;/span&gt; &lt;span class="nf"&gt;multiply&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;a&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;b&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;multiplier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&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="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Multiplier&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;int&lt;/span&gt; &lt;span class="nf"&gt;multiply&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;a&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;b&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;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&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;Despite the fact of in runtime Spring will inject the dependency (an instance of Multiplier) there is no way to inject the dependency manually, for instance when unit testing this class. &lt;/p&gt;

&lt;p&gt;The below unit test class will compile, but at runtime it's a good candidate to throw a NullPointerException, why? Because the dependency between Calculator and Multiplier was not satisfied. &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;CalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

   &lt;span class="nd"&gt;@Test&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;testAdd&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calculator&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;Calculator&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&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="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&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="o"&gt;}&lt;/span&gt;

   &lt;span class="nd"&gt;@Test&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;testMultiply&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calculator&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;Calculator&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&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="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;



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

&lt;/div&gt;
&lt;h4&gt;
  
  
  Clean Code / Screaming Architecture / Single Responsibility Principle (S from SOLID)
&lt;/h4&gt;

&lt;p&gt;Code must scream its design. And the SRP principle states that a class should have only one reason to change. This means that a class should have only one responsibility or concern. @Autowired annotation, in itself, does not violate this principle. &lt;/p&gt;

&lt;p&gt;However, if a class has multiple responsibilities and dependencies injected through the @Autowired annotation, it could be a clear sign of a violation of the SRP. In this case, it might be better to refactor the class and extract the responsibilities into separate classes.&lt;/p&gt;

&lt;p&gt;Otherwise, if constructor-based dependency injection is used instead, as more dependencies are added to your class, the constructor grows bigger and bigger and the code starts to smell, sending clear signals that something is wrong. This is described in the Clean Code / &lt;a href="https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html" rel="noopener noreferrer"&gt;Screaming Architecture pattern&lt;/a&gt; in the book written by Robert C. Martin aka Uncle Bob.&lt;/p&gt;
&lt;h4&gt;
  
  
  Complexity
&lt;/h4&gt;

&lt;p&gt;@Autowired can make the code more complex, especially when dealing with circular dependencies. When two or more classes depend on each other, it becomes hard to determine the order in which they should be instantiated. This can lead to runtime errors that are hard to debug.&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;Most likely your project doesn't need @Autowired at all&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  What should you use instead?
&lt;/h2&gt;

&lt;p&gt;The short answer is &lt;strong&gt;Constructor Injection&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In OOP we create an object by calling its constructor. If the constructor expects all required dependencies as parameters, then we can be 100% sure that the class will never be instantiated without having its dependencies injected.&lt;/p&gt;

&lt;p&gt;Below an example using Constructor-based Dependency Injection instead of @Autowired.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

   &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Multiplier&lt;/span&gt; &lt;span class="n"&gt;multiplier&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

   &lt;span class="c1"&gt;// Default constructor. It will be used by Spring to &lt;/span&gt;
   &lt;span class="c1"&gt;// inject the dependencies declared here.&lt;/span&gt;
   &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Multiplier&lt;/span&gt; &lt;span class="n"&gt;multiplier&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;multiplier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;multiplier&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;int&lt;/span&gt; &lt;span class="nf"&gt;add&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;a&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;b&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&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;int&lt;/span&gt; &lt;span class="nf"&gt;multiply&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;a&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;b&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;multiplier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&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="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Multiplier&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;int&lt;/span&gt; &lt;span class="nf"&gt;multiply&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;a&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;b&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;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&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;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

   &lt;span class="nd"&gt;@Test&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;testAdd&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calculator&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;Calculator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mock&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Multiplier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&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="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&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="o"&gt;}&lt;/span&gt;

   &lt;span class="nd"&gt;@Test&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;testMultiply&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Multiplier&lt;/span&gt; &lt;span class="n"&gt;mockMultiplier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Multiplier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;when&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mockMultiplier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;thenReturn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calculator&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;Calculator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mockMultiplier&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&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="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;Now the dependency between the two components was explicitly declared and the code design allows a mock instance of Multiplier to be injected at runtime. &lt;/p&gt;

&lt;p&gt;Also, Constructor injection helps in creating immutable objects simply because a constructor is the only possible way to create objects. Once we create a bean, we cannot alter its dependencies anymore. On the other hand, by using setter injection, it’s possible to inject the dependency after creation or change the dependency, thus leading to mutable objects which, among other things, may not be thread-safe in a multi-threaded environment and are harder to debug due to their mutability.&lt;/p&gt;

&lt;p&gt;By explicitly defining the dependencies of the class on the constructor, you can make the code more &lt;strong&gt;maintainable&lt;/strong&gt;, &lt;strong&gt;testable&lt;/strong&gt;, and &lt;strong&gt;flexible&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maintainable&lt;/strong&gt; because you rely only on OOP concepts to inject your class dependencies and any change to the class dependencies contract will be communicated to the other class with no effort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testable&lt;/strong&gt; because you have a point of injection that will allow the unit tests to pass, for instance, a mock object instead of a concrete implementation. Besides, we make this class immutable by allowing only injections at the constructing time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible&lt;/strong&gt; because you still able to add more dependencies to the class with minimum effort by adding more parameters to the default constructor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach makes it easier to understand and track the dependencies of your classes. Additionally, it makes it easier to test the class in isolation by forcing your to explicitly providing mock objects for the required dependencies at coding time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setter Injection
&lt;/h3&gt;

&lt;p&gt;One more method to do Dependency Injection using Spring is by using setter methods to inject a instance of the dependency. &lt;/p&gt;

&lt;p&gt;Below you can see an example of how Setter Injection looks like when using Spring.&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;UserService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;        

    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt; &lt;span class="c1"&gt;// Setter Injection&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;setUserRepository&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;UserRepository&lt;/span&gt; &lt;span class="n"&gt;userRepository&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;userRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userRepository&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="o"&gt;}&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;This approach can lead to problems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Optional dependencies&lt;/em&gt;. Setter Injection allows for optional dependencies, which can lead to null pointer exceptions if the dependencies are not properly checked for null values.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Incomplete object state&lt;/em&gt;. If an object is partially constructed and a setter is called, it can result in the object being in an incomplete state, which can lead to unexpected behavior or null pointer exceptions again.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Hidden dependencies&lt;/em&gt;. As the dependency is not explicitly declared in the constructor, making it harder to understand the code and its dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite the drawbacks, Setter Injection sits somewhere between the Field and the Constructor Injection because at least we have a public method that allows developers to inject mocks instead of real implementation making the class easier to test. &lt;/p&gt;

&lt;h2&gt;
  
  
  Further Considerations
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;@Autowired&lt;/em&gt; annotation can be omitted from codebases using Spring Framework 4.3 or higher and Spring will use the default constructor and inject all necessary dependencies for you when the class is being managed by the Application Context.. (&lt;a href="https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-constructor-vs-setter-injection" rel="noopener noreferrer"&gt;https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-constructor-vs-setter-injection&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;So, since the &lt;a href="https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-autowired-annotation" rel="noopener noreferrer"&gt;Spring team decided&lt;/a&gt; @Autowired should be optional to the default constructor. We can conclude since it's not helping the Spring framework to make a decision, its presence is just noise. Get rid of it!&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-constructor-vs-setter-injection" rel="noopener noreferrer"&gt;below comment&lt;/a&gt; from the Spring Framework development team gives one more reason to choose Constructor Injection as your default injection method.&lt;/p&gt;

&lt;p&gt;"Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state." and "Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class."&lt;/p&gt;

&lt;p&gt;Basically, what they are saying is by using constructor injection you can guarantee the ready-to-use state of the class. If you are using @Autowired or even setter injection your class instance can be instantiated by Spring in a bad state which can cause unexpected behaviour, such as NullPointerException.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why @Autowired even exist?
&lt;/h2&gt;

&lt;p&gt;If you need to inject optional or changeable dependencies, you may want to use @Autowired to mark the setter method (or a non-default constructor) as the point of injection. But it only makes sense if your dependency is optional or changeable and your implementation can handle the absence of that dependency (nulls).&lt;/p&gt;

&lt;p&gt;If several constructors are available and there is no primary/default constructor, at least one of the constructors must be annotated with @Autowired to instruct Spring which one to use. This is a scenario where @Autowired can be considered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;At the end of the day, @Autowired can be useful for small, simple projects, but it is not a good choice for large, complex, and production-ready projects where the code design should be open for extension, flexible, and easy to test. Instead, the recommendation is to use explicit Dependency Injection via class constructor. By doing so, you can ensure that your code remains robust and adaptable.&lt;/p&gt;

&lt;p&gt;Something that you and your team will gain for free is that the rest of the project will implicitly reflect this code design decision. Sometimes, developers never learn about proper Dependency Injection, class contracts, or even how to test code effectively simply because they use @Autowired and never question its real necessity and applicability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional reading and references
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-constructor-vs-setter-injection" rel="noopener noreferrer"&gt;https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-constructor-vs-setter-injection&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-autowired-annotation" rel="noopener noreferrer"&gt;https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-autowired-annotation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://betulsahinn.medium.com/why-is-autowired-annotation-not-recommended-4939c46da1f8" rel="noopener noreferrer"&gt;https://betulsahinn.medium.com/why-is-autowired-annotation-not-recommended-4939c46da1f8&lt;/a&gt;&lt;br&gt;
&lt;a href="https://blog.marcnuri.com/field-injection-is-not-recommended" rel="noopener noreferrer"&gt;https://blog.marcnuri.com/field-injection-is-not-recommended&lt;/a&gt;&lt;br&gt;
&lt;a href="https://reflectoring.io/constructor-injection/" rel="noopener noreferrer"&gt;https://reflectoring.io/constructor-injection/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://kinbiko.com/posts/2018-02-13-spring-dependency-injection-patterns/" rel="noopener noreferrer"&gt;https://kinbiko.com/posts/2018-02-13-spring-dependency-injection-patterns/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://blog.frankel.ch/my-case-against-autowiring/" rel="noopener noreferrer"&gt;https://blog.frankel.ch/my-case-against-autowiring/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/pulse/when-autowire-spring-boot-omar-ismail/?trk=articles_directory" rel="noopener noreferrer"&gt;https://www.linkedin.com/pulse/when-autowire-spring-boot-omar-ismail/?trk=articles_directory&lt;/a&gt;&lt;br&gt;
&lt;a href="https://eng.zemosolabs.com/when-not-to-autowire-in-spring-spring-boot-93e6a01cb793" rel="noopener noreferrer"&gt;https://eng.zemosolabs.com/when-not-to-autowire-in-spring-spring-boot-93e6a01cb793&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/41092751/spring-injects-dependencies-in-constructor-without-autowired-annotation" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/41092751/spring-injects-dependencies-in-constructor-without-autowired-annotation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spring</category>
      <category>springboot</category>
      <category>java</category>
      <category>coding</category>
    </item>
    <item>
      <title>Creating Effective Code using Java Records</title>
      <dc:creator>Felix Coutinho</dc:creator>
      <pubDate>Fri, 13 Jan 2023 17:45:34 +0000</pubDate>
      <link>https://dev.to/felixcoutinho/creating-effective-code-using-java-records-1j3l</link>
      <guid>https://dev.to/felixcoutinho/creating-effective-code-using-java-records-1j3l</guid>
      <description>&lt;p&gt;Java Records is a new feature &lt;a href="https://docs.oracle.com/en/java/javase/14/language/records.html"&gt;introduced in Java 14&lt;/a&gt; to make it easier for developers to create immutable classes. A record is a special type of class (and a new keyword too) that acts as a data container or a data object, and it's used to hold a fixed set of values.&lt;/p&gt;

&lt;p&gt;Let's check a short Java Records example.&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="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Point&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;x&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;y&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;This creates a new record class called Point, with two fields x and y. These fields are automatically marked as final, so they cannot be modified once the record is created.&lt;/p&gt;

&lt;p&gt;Under the hood a few methods are going to be generated to help you, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;constructor&lt;/em&gt; that initializes all the fields&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Accessor methods&lt;/em&gt; (getters and setters) for each field&lt;/li&gt;
&lt;li&gt;And &lt;em&gt;toString&lt;/em&gt;, &lt;em&gt;hashCode&lt;/em&gt;, and &lt;em&gt;equals&lt;/em&gt; methods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means that you don't have to write boilerplate code for these common tasks, making it much easier to create and maintain your code. And also by using Java Records you can eliminate a lot of use cases for the loved and hated &lt;a href="https://dev.to/felixcoutinho/thoughts-on-lombok-5dlk"&gt;Lombok&lt;/a&gt; library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Records?
&lt;/h2&gt;

&lt;p&gt;The short answer is Records are more &lt;em&gt;expressive&lt;/em&gt;, &lt;em&gt;readable&lt;/em&gt;  and &lt;em&gt;faster&lt;/em&gt; than traditional DTO classes.&lt;/p&gt;

&lt;p&gt;Using the example we already presented above, of a point in 2D space, you can easily use a record to clearly express that the class only has two fields and nothing else. Showing how &lt;em&gt;readable&lt;/em&gt; and &lt;em&gt;expressive&lt;/em&gt; record classes are.&lt;/p&gt;

&lt;h3&gt;
  
  
  DTOs vs Record
&lt;/h3&gt;

&lt;p&gt;This is a inevitable comparison even though DTOs are not the only use case for Java Records. Both are used to hold a fixed set of values, but they have some key differences. When we compare Records with a DTO stylish class we can see a big difference in &lt;em&gt;expressiveness&lt;/em&gt; and &lt;em&gt;readability&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;We can replace about 40 lines of code with 1 line only. Check the Point class written using the DTO pattern.&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;class&lt;/span&gt; &lt;span class="nc"&gt;PointDTO&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;int&lt;/span&gt; &lt;span class="n"&gt;x&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;int&lt;/span&gt; &lt;span class="n"&gt;y&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;PointDTO&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;x&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;y&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&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;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&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;int&lt;/span&gt; &lt;span class="nf"&gt;getX&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;x&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;int&lt;/span&gt; &lt;span class="nf"&gt;getY&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;y&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="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;toString&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="s"&gt;"PointDTO{"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="s"&gt;"x="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="s"&gt;", y="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="sc"&gt;'}'&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;boolean&lt;/span&gt; &lt;span class="nf"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;o&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="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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;o&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;getClass&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&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;PointDTO&lt;/span&gt; &lt;span class="n"&gt;pointDTO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PointDTO&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;o&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;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;pointDTO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
                &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;pointDTO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;y&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;int&lt;/span&gt; &lt;span class="nf"&gt;hashCode&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="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&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;As you can see, compared to the Record class, the DTO class contains a lot more code (boilerplate code), including the constructor, getter methods, and the methods toString, hashCode, and equals which are common to most DTOs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unlike DTOs, records are immutable by nature, meaning their fields cannot be modified once the record is created. This makes records more suitable for functional programming and improves code safety.&lt;/li&gt;
&lt;li&gt;Records have built-in support for common methods like toString, hashCode, and equals, which eliminates the need for boilerplate code.&lt;/li&gt;
&lt;li&gt;Records are a more modern and expressive way of creating data classes compared to DTOs, which could make it easier for new developers to read and understand the codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And we can point out more reasons to use Records.&lt;/p&gt;

&lt;h3&gt;
  
  
  JVM loves Records (and vice versa)
&lt;/h3&gt;

&lt;p&gt;Java Records are more efficient than traditional classes in terms of memory usage and performance because of their immutable nature, the way they are implemented in the JVM, and the techniques like &lt;em&gt;compacting&lt;/em&gt; and &lt;em&gt;inlining&lt;/em&gt; that the JVM can apply to classes markes as records. &lt;/p&gt;

&lt;p&gt;Records eliminate the need for &lt;a href="https://www.oracle.com/java/technologies/javase/seccodeguide.html"&gt;defensive copying&lt;/a&gt; (check Guideline 6-2), which can improve performance by reducing the number of operations that need to be performed on the data.&lt;/p&gt;

&lt;p&gt;Because Records don't have any additional methods or fields, the JVM can use more aggressive optimization techniques for records, like &lt;a href="https://www.ibm.com/docs/en/sdk-java-technology/8?topic=compiler-how-jit-optimizes-code"&gt;inlining&lt;/a&gt; (check Phase 1), that can further improve performance. But, it doesn't mean more methods can be added, you still can adding more methods as you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disadvantages of using Records
&lt;/h2&gt;

&lt;p&gt;As with everything in life (technology especially), there are also some drawbacks when using records. &lt;/p&gt;

&lt;p&gt;Java Records are not suitable for use as JPA (Java Persistence API) entity classes because they have some limitations that make them incompatible with the requirements of JPA entities.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JPA entities are required to have a no-arg constructor, which is not provided by default for records. This means that you would have to manually add a no-arg constructor to the record class, which would defeat the purpose of using a record in the first place.&lt;/li&gt;
&lt;li&gt;JPA entities are required to have setter methods for each field so that the entity manager can update the fields in the database. However, records do not have setter methods by default, as their fields are automatically marked as final.&lt;/li&gt;
&lt;li&gt;JPA entities can have additional methods and fields that are not part of the record.&lt;/li&gt;
&lt;li&gt;JPA entities can be extended or implemented interfaces or classes, while records cannot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see while records provide a concise and efficient way to create immutable classes, they are not suitable for use as JPA entities due to the limitations on constructors, setter methods, additional methods, fields and interfaces or classes that JPA entities require.&lt;/p&gt;

&lt;h2&gt;
  
  
  To wrap up
&lt;/h2&gt;

&lt;p&gt;When I first saw Records my thought was to replace all of my DTOs and JPA Entities with Records right away but I was partially wrong. Clearly, DTOs and data classes are good candidates to be replaced by Records but not our lovely and long JPA Entities because of the limitation we discussed here. &lt;/p&gt;

&lt;p&gt;One more time writing and diving into concepts I like such as Records made me more confident to make choices about whether recommend or not Records for my Java projects or even better to refactor or not to use Records. And due to the simple use and low cost  of Records it can be used in different parts of a Java codebase and not blocking you to use other type of classes such as Entities in different parts of the code base.&lt;/p&gt;

&lt;p&gt;What about you? Are you using Records in your projects? How is the experience so far? &lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>architecture</category>
      <category>records</category>
    </item>
    <item>
      <title>Lombok: The Good, The Bad, and The Controversial</title>
      <dc:creator>Felix Coutinho</dc:creator>
      <pubDate>Tue, 01 Feb 2022 22:32:26 +0000</pubDate>
      <link>https://dev.to/felixcoutinho/thoughts-on-lombok-5dlk</link>
      <guid>https://dev.to/felixcoutinho/thoughts-on-lombok-5dlk</guid>
      <description>&lt;p&gt;Java developers, particularly those coming from other programming languages, have long complained about the overwhelming amount of boilerplate code found in Java codebases. In Object-Oriented Java development, the necessity of ensuring encapsulation and immutability of objects only adds to the amount of boilerplate code required. This issue is a common pain point for developers and can be exemplified by tens or even hundreds of lines of getter and setter methods per source file, as well as extensive class constructors. In response to this problem, Project Lombok was created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lombok
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Project Lombok is a java library that automatically plugs into your editor and building tools, spicing up your java. Never write another getter or equals method again, with one annotation your class has a fully featured builder, automates your logging variables, and much more. (from &lt;a href="https://projectlombok.org/" rel="noopener noreferrer"&gt;https://projectlombok.org/&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically, Lombok uses &lt;a href="https://en.wikipedia.org/wiki/Metaprogramming" rel="noopener noreferrer"&gt;meta-programming&lt;/a&gt; to generate code at compile time. In addition to the possibility of generating getters/setters methods, it can generate equals methods, hash code and a variety of class constructors. Besides the possibility of generating class-level attributes, for instance, a logger attribute using LOG4J. It may seem mysterious, but in fact, Lombok uses two native Java features to generate this code. Let's explore these features below.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does Lombok work?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Annotations
&lt;/h3&gt;

&lt;p&gt;Annotations were introduced in Java a long time ago, in version 6. And Lombok has a series of annotations that can be used to identify/mark the need to generate new code within that class.&lt;/p&gt;

&lt;h3&gt;
  
  
  AST (Abstract Syntax Tree)
&lt;/h3&gt;

&lt;p&gt;Abstract Syntax Tree is the way the compiler represents the steps that need to be performed for the final program to be generated. AST Java is a kind of intermediate structure that is created before the byte code is generated. Java has its own AST and it can be manipulated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9rnt0bv58zlolsix5w0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9rnt0bv58zlolsix5w0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image source [&lt;a href="https://sewiki.iai.uni-bonn.de/_media/research/jtransformer/lmp.jpg" rel="noopener noreferrer"&gt;https://sewiki.iai.uni-bonn.de/_media/research/jtransformer/lmp.jpg&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;So, if we join these two technologies/features everything starts to make sense. During the compilation phase, Lombok annotations are identified and Lombok manipulates AST to insert code that did not exist before into existing classes.&lt;/p&gt;

&lt;p&gt;However, Lombok doesn't do this in a snap. It needs to intercept calls to the Java compiler in order to handle the intermediate code that will be generated. This is done through plugins, either in your IDE (IntelliJ, VSCode, Eclipse) or via building tools (Maven/Gradle/Make). If your IDE or your dependency/build manager does not support Lombok your code will not compile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Compilation time
&lt;/h3&gt;

&lt;p&gt;Due to Lombok performing its magic at compilation time, you can expect an increase in the compilation time of your Java project/codebase. And this increase can have a high impact, especially on large codebases, the more code to generate the more AST to handle. The Lombok development team has been working to lessen this impact and has succeeded, but the time is still longer with Lombok than without it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Java Standards
&lt;/h3&gt;

&lt;p&gt;Let's say you're trying to compile your source code using only javac (the java compiler) and the source code uses a &lt;em&gt;get&lt;/em&gt; method generated by Lombok in this case you will get a compilation error saying that the &lt;em&gt;get&lt;/em&gt; method doesn't exist.&lt;/p&gt;

&lt;p&gt;It happens because a source code that uses Lombok annotations is not a valid Java source code. (Controversial but sincere)&lt;/p&gt;

&lt;p&gt;Is this a problem? The answer is yes and no. Yes, because you will always depend on Lombok plugins for your source code compilation to work. No, because in most cases developers use IDEs or building tools to compile their Java code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compatibility
&lt;/h3&gt;

&lt;p&gt;Another point of attention is the compatibility with future and previous versions of Java. With each version, Java may change the way AST is generated and interpreted. In version 8 it can be one way and in version 9 another way. So Project Lombok needs to update its dependency library to generate the code in the most up-to-date way, and of course, maintain backward compatibility as well.&lt;/p&gt;

&lt;p&gt;If you are using Lombok, it is possible that your project will fail to compile if you upgrade your Java release.&lt;/p&gt;

&lt;p&gt;It's a problem? Yes and no. Yes, because you will only notice that your code stopped compiling after you perform the Java upgrade. No, because Project Lombok usually releases library updates before the final versions of Java. But remember, if you use Lombok be aware of possible future compilation failures for the reason I've described above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Boilerplate code
&lt;/h3&gt;

&lt;p&gt;This is where Lombok gains popularity, in the emotional and most visible part of the source code. No doubt Lombok drastically reduces the amount of boilerplate code in your Java classes, especially in domain classes (TOs, DTOs, Entities) where usually we have a lot of class-level attributes.&lt;/p&gt;

&lt;p&gt;If we count 3 lines of code for each &lt;em&gt;get&lt;/em&gt; method and 3 more lines of code for each &lt;em&gt;set&lt;/em&gt; method we will end up having a reason of 6 lines less for each class attribute if you are using Lombok to generate &lt;em&gt;get&lt;/em&gt; and &lt;em&gt;set&lt;/em&gt; for all of the class attributes. In a class with 10 attributes, you will save 60 lines of code minus the lines containing Lombok annotations. Besides equals, hash code, toString and other methods.&lt;/p&gt;

&lt;p&gt;That is good? Yes and no. Yes, because your source code file will be smaller, simpler, and for instance, if you add a new attribute the boilerplate code related to that attribute will be generated automatically. No, because all IDEs, from the simplest to the most complete, can generate this boilerplate code with one or two clicks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluding
&lt;/h2&gt;

&lt;p&gt;Lombok has its advantages, but it also has its drawbacks. A major issue in my opinion is that it can make your code &lt;em&gt;less readable&lt;/em&gt;, especially for developers who are not familiar with Lombok's annotations. This is because the annotations can hide what the code is doing, and may make it more difficult for other developers to understand what is happening behind the scenes. &lt;/p&gt;

&lt;p&gt;Another potential drawback is that Lombok is not supported by all IDEs out of the box, which can make it more difficult to set up and use. And Lombok doesn't always play nicely with other libraries or frameworks, which can cause compatibility issues and make debugging tricky and longer.&lt;/p&gt;

&lt;p&gt;Despite these, Lombok can be a powerful tool for simplifying your code and reducing boilerplate. It's up to you to weigh the &lt;a href="https://dev.to/felixcoutinho/highly-standardized-code-syndrome-54c9"&gt;pros and cons&lt;/a&gt; and decide whether or not it's worth using this library in your project. Ultimately, whether or not to use Lombok comes down to a matter of personal preference and what works best for your team and your project.&lt;/p&gt;

&lt;h4&gt;
  
  
  Personally
&lt;/h4&gt;

&lt;p&gt;In my personal experience, I tend to avoid using Lombok in my projects. When discussing this topic with my team, I share the points mentioned in this post, and we make a decision based on the project requirements and context. In some Java teams, we've used Lombok, and in others, we haven't, without any negative impact on the project. One noteworthy project I worked on in recent years did not use Lombok, yet it was still very successful. The decision to use Lombok or not depends on a variety of factors and should be evaluated on a case-by-case basis.&lt;/p&gt;

&lt;p&gt;The clear advantage is having less code to maintain. However, this type of code (boilerplate) is not considered critical and can be easily generated by your favourite IDE. And the drawback is adding more complexity to your codebase, especially on the project building time and compatibility with future Java versions.&lt;/p&gt;

&lt;p&gt;Some of the use cases for using Lombok can be tackled by using Java Records, &lt;a href="https://dev.to/felixcoutinho/creating-effective-code-using-java-records-1j3l"&gt;check my other article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lombok will not determine the success or failure of your project. But if you need to decrease the size of your Java classes Lombok can be helpful. But don't forget to take into account the points that were listed here.&lt;/p&gt;

</description>
      <category>java</category>
      <category>lombok</category>
      <category>jvm</category>
      <category>programming</category>
    </item>
    <item>
      <title>Designing cloud-native microservices [Deck/References/Links]</title>
      <dc:creator>Felix Coutinho</dc:creator>
      <pubDate>Tue, 01 Feb 2022 22:15:23 +0000</pubDate>
      <link>https://dev.to/felixcoutinho/designing-cloud-native-microservices-talk-4946</link>
      <guid>https://dev.to/felixcoutinho/designing-cloud-native-microservices-talk-4946</guid>
      <description>&lt;p&gt;Hello fellow developers and architects! As we venture into the world of cloud-native microservices, I have compiled a collection of valuable resources that formed the basis of my "Designing Cloud-Native Microservices Using Patterns" presentation. Whether you are a seasoned developer or an aspiring architect, these references provide an excellent starting point for developing a microservices mindset and creating your microservices with skill.&lt;/p&gt;

&lt;p&gt;There are a lot of resources available for designing microservices, including cloud-native microservices. These resources can help you overcome challenges and provide a comprehensive perspective. If you're interested, you can check out my presentation deck for future reference when starting your projects.&lt;/p&gt;

&lt;p&gt;🎨 &lt;strong&gt;Presentation Deck&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://speakerdeck.com/felixcoutinho/designing-cloud-native-microservices-using-patterns" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--o8sDoUFv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://files.speakerdeck.com/presentations/08b1596b2a9744cca4fcc51343cd8c70/slide_0.jpg%3F18269016" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://speakerdeck.com/felixcoutinho/designing-cloud-native-microservices-using-patterns" rel="noopener noreferrer" class="c-link"&gt;
          Designing cloud-native microservices using patterns - Speaker Deck
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Designing cloud-native microservices using patterns 
Felix Coutinho
Cloud-native applications are a collection of small, independent, and loosely coupled services. How can you as a developer or an architect design microservices that comply with this definition? And more, how can you do this using industry-level design patterns such as fanout, mat-view, observability, CQRS?

The intent of this talk is to give real-world examples and feed the participants with confidence that cloud-native microservices are possible to implement since you design them properly.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--hTR4_2pe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://d1eu30co0ohy4w.cloudfront.net/assets/favicon-bdd5839d46040a50edf189174e6f7aacc8abb3aaecd56a4711cf00d820883f47.png" width="512" height="512"&gt;
        speakerdeck.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Now, if you're ready to dive deeper, I encourage you to engage with the video recording of the presentation. Please note that the recording is in &lt;strong&gt;Portuguese&lt;/strong&gt;, my apologies for any inconvenience. But if you need it in English, check the TDC Online section below.&lt;/p&gt;

&lt;p&gt;📹 &lt;strong&gt;Video Recording (Portuguese only)&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/nSkh2rDm4uw?start=5841"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you're eager to explore further and expand your knowledge, I also had the honor of delivering this presentation at the TDC Connection conference. To gain access to this content, a subscription is required. Here's a glimpse:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DZh7hWGp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urkugtop0zj5n0eqrge4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DZh7hWGp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urkugtop0zj5n0eqrge4.png" alt="TDC Online" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TDC Online
&lt;/h3&gt;

&lt;p&gt;For more details on the TDC Connection conference and how to access the content, visit: &lt;a href="https://thedevconf.com/tdconline"&gt;TDC Online&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This resource compilation includes books and links to help you better understand and use cloud-native microservices. It's a valuable tool for enhancing your knowledge and implementation of this technology.&lt;/p&gt;

&lt;p&gt;If you want to recommend books, please add a comment to this article.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Books
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/book"&gt;Dive into Design Patterns – Alexander Shvets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3gyF40F"&gt;Microservices patterns – Chris Richardson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3st5cj1"&gt;Domain-Driven Design – Eric Evans&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3LeTGAJ"&gt;Designing Distributed Systems – Brendan Burns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3otijjh"&gt;Monolith to Microservices – Sam Newman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3B4Gsl6"&gt;Building Microservices – Sam Newman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learning.oreilly.com/library/view/beyond-the-twelve-factor/9781492042631/"&gt;Beyond the Twelve-Factor App – Kevin Hoffman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3GzZVeS"&gt;Patterns, Principles, and Practices of Domain-Driven Design – Scott Millett, Nick Tune&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://download.microsoft.com/download/b/b/6/bb69622c-ab5d-4d5f-9a12-b81b952c1169/clouddesignpatternsbook-pdf.pdf"&gt;Cloud Design Patterns – Alex Homer, John Sharp, Larry Brader, Masashi Narumoto, Trent Swanson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3GCtuMO"&gt;Building Event-Driven Microservices – Adam Bellemare&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🔗 Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/cncf/toc/blob/main/DEFINITION.md"&gt;CNCF Definition of Cloud-Native&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/architecture/cloud-native/definition"&gt;Microsoft Documentation on Cloud-Native Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.redhat.com/en/topics/cloud-native-apps"&gt;Red Hat's Insights on Cloud-Native Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://microservices.io/index.html"&gt;Microservices.io – A Comprehensive Resource&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use these resources to begin your journey to becoming a cloud-native microservices developer or architect. Use them as inspiration to develop your skills in creating and executing solutions that utilize cloud-native patterns. And again, feel free to explore further, educate yourself, and share your findings with us in the comments.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>cloud</category>
      <category>cloudnative</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>The Highly Standardized Code Syndrome</title>
      <dc:creator>Felix Coutinho</dc:creator>
      <pubDate>Tue, 01 Feb 2022 22:10:33 +0000</pubDate>
      <link>https://dev.to/felixcoutinho/highly-standardized-code-syndrome-54c9</link>
      <guid>https://dev.to/felixcoutinho/highly-standardized-code-syndrome-54c9</guid>
      <description>&lt;p&gt;Dear reader, this article is about a theory under construction and it's been improved and nurtured over time by me. Your feedback is more than appreciated.&lt;/p&gt;

&lt;h2&gt;
  
  
  A little bit of history
&lt;/h2&gt;

&lt;p&gt;There was a time when programming standards and good practices were created in silos. Big companies like IBM, Microsoft, Oracle, Sun and even NASA had their best practice manuals and some were kept as secret as they did with industrial secrets. As the practice of developing software became more common, not-so-large companies started to create their own software and the desire for standardization became increasingly evident, as is the goal of all industrial practices.&lt;/p&gt;

&lt;p&gt;Over the years, the Software Engineering literature has established a series of standards and good practices that have taken software development to an industrial level. Design patterns, paradigms, principles, concepts and techniques were established over time so that the source code produced would have a more industrial and less personal character. Furthermore, introducing these best practices allows the source code to be better understood, better maintainable and at a lower cost for everyone, programmers and companies.&lt;/p&gt;

&lt;p&gt;This level of maturity has allowed software development to become a reproducible discipline anywhere in the world, true engineering.&lt;/p&gt;

&lt;p&gt;However, many of these standards have been thought, grounded, tested and established in silos. Real problems in real teams and companies that do not necessarily reproduce the scenario that a developer lives. In addition, these concepts are often mutually exclusive, when applying one of them you cannot apply the other.&lt;/p&gt;

&lt;p&gt;As well as the lack of standards is a problem for the delivered source code, and the use of too many of these standards can be a problem as well. This is the fundamental ground where can establish the Highly Standardized Code Syndrome.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Highly Standardized Code Syndrome occurs when a software engineer believes he needs to use as many design patterns, principles, concepts and techniques as possible from the existing literature or from the industry. Consequently, his code takes a long time to be produced and delivered and he strongly believes that this will guarantee the final quality of the code produced - Felix Coutinho 2021&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In some ways the Highly Standardized Code Syndrome is comparable or I can say has its foundations in the &lt;a href="http://web.archive.org/web/20130731202547/http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf" rel="noopener noreferrer"&gt;historical article&lt;/a&gt; from Donald E. Knuth as you can see below.&lt;/p&gt;

&lt;p&gt;"Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: &lt;em&gt;premature optimization is the root of all evil&lt;/em&gt;. Yet we should not pass up our opportunities in that critical 3%." (The emphasis is mine)&lt;/p&gt;

&lt;p&gt;Of course, the Highly Standardized Code Syndrome is about standards and not about optimization but they are quite related due to the nature of the intention of their use which is the outcome of the work. In both cases, it can fail a project or at least delay of the delivery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detecting the syndrome
&lt;/h2&gt;

&lt;p&gt;The picture below can give you a clear sense of when the Highly Standardized Code Syndrome arises. The ascendance and the peak of the curve represent the first symptoms of the syndrome&lt;/p&gt;

&lt;p&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%2Fkgojv9r17uw5a6h2o828.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%2Fkgojv9r17uw5a6h2o828.png" alt="Symptoms" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image by Flavio Copes via Twitter&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Feedback first, optimization last
&lt;/h2&gt;

&lt;p&gt;A good exercise for software developers, architects and engineers is finding the right balance when applying existing industry standards. &lt;/p&gt;

&lt;p&gt;The simplest formula we can establish is &lt;strong&gt;&lt;em&gt;problem&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;scenario&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;solution&lt;/em&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In other words, you should wait until you have a real problem sourced by feedback and then you can find a solution within your scenario. Otherwise, the result will be an excess of solutions to problems that you don't have at all which will very possibly result in the Highly Standardized Code Syndrome. The developer will have spent a lot of time on problems that he doesn't have.&lt;/p&gt;

&lt;p&gt;And in general, finding the right balance between standardization and flexibility is important for a successful software development project.&lt;/p&gt;

&lt;p&gt;[Changelog]&lt;br&gt;
6th version on Feb 9th, 2023&lt;br&gt;
5th version on Feb 8th, 2022&lt;br&gt;
4th version on Feb 1st, 2022&lt;br&gt;
3rd version on Aug 21th, 2021&lt;br&gt;
2nd version on Jul 21st, 2021&lt;br&gt;
1st version on May 13th, 2021 &lt;/p&gt;

</description>
      <category>programming</category>
      <category>computerscience</category>
      <category>systemdesign</category>
      <category>philosophy</category>
    </item>
  </channel>
</rss>
