<?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: diegopaniago</title>
    <description>The latest articles on DEV Community by diegopaniago (@diegopaniago).</description>
    <link>https://dev.to/diegopaniago</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%2F187426%2Fc769e101-8ba7-4158-be26-8022feebf2b4.jpeg</url>
      <title>DEV Community: diegopaniago</title>
      <link>https://dev.to/diegopaniago</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/diegopaniago"/>
    <language>en</language>
    <item>
      <title>Contextos Delimitados, Domínios e Agregados</title>
      <dc:creator>diegopaniago</dc:creator>
      <pubDate>Sat, 08 Jul 2023 04:08:17 +0000</pubDate>
      <link>https://dev.to/diegopaniago/contextos-delimitados-dominios-e-agregados-4pld</link>
      <guid>https://dev.to/diegopaniago/contextos-delimitados-dominios-e-agregados-4pld</guid>
      <description>&lt;p&gt;O &lt;strong&gt;Domain Driven Design (DDD)&lt;/strong&gt; é uma abordagem de design de software que coloca o foco no domínio do negócio, em vez de apenas na tecnologia. Uma das principais técnicas utilizadas no DDD é o conceito de &lt;strong&gt;contextos delimitados&lt;/strong&gt; e &lt;strong&gt;mapeamento de domínios&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contextos delimitados&lt;/strong&gt; referem-se a áreas específicas do negócio que têm um significado bem definido e uma fronteira clara. Cada contexto delimitado deve ser tratado como uma unidade autônoma e deve ter sua própria &lt;em&gt;linguagem ubíqua&lt;/em&gt;, que é uma linguagem comum compartilhada por todas as partes interessadas em um contexto.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;mapeamento de domínios&lt;/strong&gt;, por sua vez, é o processo de mapear as entidades, agregados, eventos e outras construções do domínio para o código que implementa o sistema. Isso ajuda a garantir que o design do software reflita com precisão o domínio do negócio e que o código seja fácil de manter e modificar.&lt;/p&gt;

&lt;p&gt;Ao usar contextos delimitados e mapeamento de domínios, os desenvolvedores podem criar sistemas de software que sejam mais fáceis de manter e modificar. Isso ocorre porque cada contexto delimitado é tratado como uma unidade autônoma e independente, o que significa que as mudanças em um contexto não afetarão os outros contextos. Além disso, o mapeamento de domínios ajuda a garantir que o código reflita com precisão o domínio do negócio, o que significa que as mudanças no domínio podem ser facilmente refletidas no código.&lt;/p&gt;

&lt;p&gt;Outra vantagem do uso de contextos delimitados e mapeamento de domínios é que isso pode levar a um baixo acoplamento entre os diferentes componentes do sistema. Isso significa que as mudanças em um componente não afetarão os outros componentes, o que torna o sistema mais flexível e escalável.&lt;/p&gt;

&lt;p&gt;Em resumo, o uso de contextos delimitados e mapeamento de domínios no Domain Driven Design pode levar a sistemas de software mais fáceis de manter e modificar, com um baixo acoplamento entre os diferentes componentes do sistema. Isso ajuda a garantir que o software reflita com precisão o domínio do negócio e que possa ser facilmente alterado conforme as necessidades do negócio mudam ao longo do tempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contextos, domínios e agregados
&lt;/h2&gt;

&lt;p&gt;Contextos, domínios e agregados são conceitos fundamentais no Domain Driven Design (DDD), uma abordagem de design de software que tem como objetivo principal criar um software que reflita com precisão o domínio de negócio.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contextos delimitados&lt;/strong&gt;: São áreas específicas do domínio de negócio que são tratadas como unidades autônomas e independentes dentro do sistema de software. Cada contexto delimitado possui suas próprias regras de negócio, entidades, agregados, eventos e linguagem específica. Essa divisão em contextos delimitados ajuda a garantir que diferentes partes do sistema sejam tratadas de forma separada e que mudanças em um contexto não afetem outros.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Domínio&lt;/strong&gt;: É o conjunto de conhecimentos, regras e termos específicos que definem o negócio. No DDD, o foco é entender profundamente o domínio e refleti-lo no código e na estrutura do software. O mapeamento de domínios é o processo de traduzir as construções do domínio, como conceitos, entidades, regras e relacionamentos, para o design e implementação do software.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agregados&lt;/strong&gt;: São conjuntos de objetos relacionados que são tratados como unidades coesas dentro do domínio. Cada agregado possui uma raiz de agregado, que é uma entidade que atua como a única entrada para o agregado e encapsula a consistência e a integridade interna do mesmo. Os agregados ajudam a organizar as entidades relacionadas em unidades lógicas e garantem a consistência das operações dentro dessas unidades.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esses conceitos do Domain Driven Design ajudam a criar um software que reflita com precisão o domínio de negócio e seja mais fácil de entender, modificar e manter.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A modelagem de software é uma atividade de design, não uma tradução direta das regras de negócio em código." - Eric Evans&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ddd</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Desenvolvedores, Carga Cognitiva e Demissões</title>
      <dc:creator>diegopaniago</dc:creator>
      <pubDate>Thu, 07 Apr 2022 12:54:47 +0000</pubDate>
      <link>https://dev.to/diegopaniago/desenvolvedores-carga-cognitiva-e-demissoes-5fh7</link>
      <guid>https://dev.to/diegopaniago/desenvolvedores-carga-cognitiva-e-demissoes-5fh7</guid>
      <description>&lt;p&gt;Comumente, vemos empresas de tecnologia que dão total liberdade para os desenvolvedores escolherem a melhor tecnologia, plataforma e frameworks para um projeto. Isso, na realidade, é muito positivo e sempre encorajo as empresas a oferecerem essa liberdade ao time de desenvolvedores.&lt;/p&gt;

&lt;p&gt;No entanto, não podemos negar que isso gera um problema sério quando os desenvolvedores não consideram a magnitude do desafio que podem estar enfrentando.&lt;/p&gt;

&lt;p&gt;Esse desafio é conhecido como carga cognitiva alta, ou seja, um único desenvolvedor precisa dominar várias tecnologias, frameworks e plataformas para trabalhar em um projeto, além de ter que dominar a regra de negócio.&lt;/p&gt;

&lt;p&gt;Essa situação, além de ser comum, acarreta sérios problemas para o negócio da empresa, pois tende a aumentar consideravelmente a curva de aprendizado dos novos desenvolvedores, o tempo necessário para encontrar pessoas com habilidades tecnológicas adequadas e, pior ainda, aumenta o estresse das pessoas envolvidas nos projetos, devido à carga cognitiva excessiva, resultando, muitas vezes, em demissões (voluntárias ou não).&lt;/p&gt;

&lt;p&gt;É necessário que, de alguma forma, as pessoas se organizem e tenham consciência de que uma variedade excessiva pode causar os problemas mencionados anteriormente.&lt;/p&gt;

&lt;p&gt;Além disso, há um cenário bastante comum em que um único time precisa dominar uma quantidade muito grande de regras de negócio, o que novamente gera uma carga cognitiva elevada e torna o projeto desinteressante, desafiador e estressante.&lt;/p&gt;

&lt;p&gt;A cereja do bolo é a criação de microserviços sem uma reflexão aprofundada sobre os contextos de negócio, necessidades reais baseadas em dados e arquitetura, o que posteriormente resulta em uma enorme demanda de trabalho e complexidade para realizar tarefas que poderiam ser simples, como CI/CD, documentação e integração de serviços.&lt;/p&gt;

&lt;p&gt;Portanto, é fundamental ter cuidado com a quantidade de carga cognitiva adicionada a um projeto. Gestores, arquitetos, Scrum Masters e Tech Leads devem ser responsáveis por essa preocupação, mas é importante que toda a equipe seja ensinada a pensar com cautela nas soluções propostas para os problemas enfrentados.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>management</category>
      <category>burnout</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Software Legado, Refatoração e Catástrofes</title>
      <dc:creator>diegopaniago</dc:creator>
      <pubDate>Mon, 19 Apr 2021 10:38:23 +0000</pubDate>
      <link>https://dev.to/diegopaniago/software-legado-refatoracao-e-catastrofes-2fci</link>
      <guid>https://dev.to/diegopaniago/software-legado-refatoracao-e-catastrofes-2fci</guid>
      <description>&lt;p&gt;Desde o meu primeiro dia na carreira de desenvolvedor, sempre ouvi falar com desdém a palavra "legado".&lt;/p&gt;

&lt;p&gt;Na minha vida, nunca passei por um lugar onde não houvesse o tal "legado". Isso me levou a um questionamento inevitável: será que em nenhum lugar deste planeta existe um software legado bom?&lt;/p&gt;

&lt;p&gt;Era realmente inquietante para mim ouvir a palavra "legado" e perceber os arrepios das pessoas ao redor.&lt;/p&gt;

&lt;p&gt;A resposta para isso veio com o tempo.&lt;/p&gt;

&lt;p&gt;Primeiramente, devemos entender que um software é composto por código e que o código, assim que vai para produção, se torna "legado". Não existem meias-palavras para isso, o código de hoje pode se tornar uma porcaria amanhã.&lt;/p&gt;

&lt;p&gt;Devemos entender também que não necessariamente o código que pode se tornar uma porcaria amanhã significa apenas um software com bugs. Existem outras possibilidades, como performance ruim, manutenção difícil, requisitos que mudaram com o tempo ou até mesmo envelhecimento causado pelo uso de tecnologias e bibliotecas descontinuadas.&lt;/p&gt;

&lt;p&gt;Existem sim softwares legados de alta qualidade que enfrentam minimamente os problemas que mencionei.&lt;/p&gt;

&lt;p&gt;Esses sistemas bem-sucedidos têm um segredo muito simples: a refatoração!&lt;/p&gt;

&lt;p&gt;Softwares que atingem sua completude e entram na fase de manutenção devem ser constantemente melhorados. E manter um software não significa apenas realizar monitoramentos e medir a satisfação dos usuários (recomendo fortemente que façam).&lt;/p&gt;

&lt;p&gt;De tempos em tempos, um software legado precisa ser analisado pelos programadores, devido a insatisfações, apontamentos feitos pelo monitoramento, requisitos que mudaram ou até mesmo novas funcionalidades que devem ser adicionadas.&lt;/p&gt;

&lt;p&gt;E é nesse momento que o segredo para possuir um legado de alta qualidade entra em jogo: a regra do escoteiro.&lt;/p&gt;

&lt;p&gt;Sempre deixe o código melhor do que quando você o encontrou.&lt;/p&gt;

&lt;p&gt;Não acumule dívidas técnicas, resolva-as na próxima sprint ou no menor tempo possível, ou melhor ainda, não as crie. Acumular muitas dívidas pode inviabilizar a manutenção e resultar na catástrofe de refazer um sistema.&lt;/p&gt;

&lt;p&gt;Reflicta sempre sobre o quanto é fácil trabalhar naquele projeto. As complexidades devem ser, em sua maioria, apenas do negócio e não da tecnologia. A tecnologia deve ser a solução, não o problema.&lt;/p&gt;

&lt;p&gt;Não exponha a seu time de negócio ou ao Product Owner as refatorações que você precisa fazer. O programador deve sempre ter a autoridade técnica. Portanto, apenas estime aquilo que deve ser estimado e negocie prazos com a área de negócios, incluindo sempre aquilo que deve ser feito, inclusive as refatorações desejadas.&lt;/p&gt;

&lt;p&gt;Isso permitirá que você tenha a possibilidade de resolver as dificuldades daquele código problemático de determinada feature.&lt;/p&gt;

&lt;p&gt;É claro que, se o programador deixar as dívidas técnicas se acumularem, será preciso em algum momento negociar atividades de refatoração extensas com a equipe de negócios. É por esse motivo que se deve evitar o acúmulo de dívidas no código.&lt;/p&gt;

&lt;p&gt;É necessário entender que refatoração não significa refazer o software, mas sim melhorar parcialmente o que já existe sem quebrar o sistema.&lt;/p&gt;

&lt;p&gt;Podemos concluir que se o legado é ruim, é porque o programador o construiu assim. Não surgiram milhares de linhas de código mal escritas da noite para o dia no projeto.&lt;/p&gt;

&lt;p&gt;Programadores que herdam legados problemáticos devem ter o profissionalismo de expor a situação juntamente com um plano de ação para o time de negócios e gestão, para que juntos definam cronogramas e atividades para resolver os problemas. Pode ser que nesse momento seja necessária a decisão de refazer um sistema, dependendo da quantidade de dívidas e do investimento necessário para resolvê-las.&lt;/p&gt;

&lt;p&gt;Podemos perceber que não existe um bom software legado que não tenha uma atenção técnica mínima de tempos em tempos, ou seja, mantê-lo corretamente.&lt;/p&gt;

&lt;p&gt;Aqui vai um recado para os programadores presenteados com softwares legados problemáticos: não existe um caminho saudável para resolver os problemas sem uma boa cobertura de testes automatizados, sejam eles de unidade ou integração (tenha ambos, preferencialmente).&lt;/p&gt;

&lt;p&gt;Ter certeza de que suas mudanças não quebram o sistema é vital para qualquer software em qualquer momento do seu ciclo de vida, não apenas para legados.&lt;/p&gt;

&lt;p&gt;Por fim, não caia na falácia de que um software concluído só precisa de manutenção quando algo dá errado ou que, se está funcionando, não precisa mexer. Mantenha seu software corretamente, com monitoramentos, testes automatizados e não deixe o código envelhecer. Sempre pratique a refatoração quando necessário.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Art of DRY</title>
      <dc:creator>diegopaniago</dc:creator>
      <pubDate>Wed, 11 Mar 2020 21:36:41 +0000</pubDate>
      <link>https://dev.to/diegopaniago/the-art-of-dry-42md</link>
      <guid>https://dev.to/diegopaniago/the-art-of-dry-42md</guid>
      <description>&lt;p&gt;This is my first article written in English, so please bear with me and provide your feedback.&lt;/p&gt;

&lt;p&gt;When I mention "The Art of DRY," I am referring to the concept of Don't Repeat Yourself, which I first encountered in Robert C. Martin's book, Clean Code.&lt;/p&gt;

&lt;p&gt;At first glance, this concept seems obvious and easy to implement. However, I have come to realize that it is not only challenging to achieve but also difficult to identify when duplication occurs beyond just code repetition.&lt;/p&gt;

&lt;p&gt;Many times, you may find blocks of code repeated throughout your software. Identifying what can be made reusable and applying techniques such as object-oriented programming and design patterns can help eliminate these duplications.&lt;/p&gt;

&lt;p&gt;Duplication doesn't only exist in explicit code but can also be found in terminal commands, deployment processes, or routine test runs.&lt;/p&gt;

&lt;p&gt;Once you grasp that DRY encompasses more than just eliminating code duplication, you enter a different realm.&lt;/p&gt;

&lt;p&gt;To fully benefit from the art of DRY, you need to explore other techniques and technologies that can eliminate all the redundant actions you repeatedly perform.&lt;/p&gt;

&lt;p&gt;Here are some practices that have delivered significant automation results for me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Continuous Integration (CI):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whenever I commit and push my code, the CI tool (such as Azure DevOps and GitLab) automatically runs my test suite and provides feedback on whether my changes work well with the existing codebase.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Continuous Deployment (CD):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the CI pipelines complete, we automatically deploy new artifacts to staging environments and, in some cases, even to production. This is incredibly useful as it ensures that I don't forget to update staging areas for product owners and stakeholders to validate changes or refresh production environments and create git tags.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Bash:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The power to automate tasks that you no longer wish to perform manually. This speaks for itself.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Docker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apart from other benefits, Docker allows me to skip the installation process from scratch. Being able to spin up my development environment with a single command or even when I boot my PC feels like a dream come true.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aliases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating aliases for frequently used git commands, test runs, or any other repetitive terminal tasks is a fantastic way to save time and boost productivity.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I hope you now understand that DRY extends beyond removing code duplication.&lt;/p&gt;

&lt;p&gt;Eliminating everything that can be automated using appropriate tools is also a part of DRY.&lt;/p&gt;

&lt;p&gt;Please share your comments, and thank you for reading.&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>productivity</category>
      <category>devlife</category>
      <category>agile</category>
    </item>
    <item>
      <title>Eventos de Domínio e Como Tornar o Desacoplamento Algo Real</title>
      <dc:creator>diegopaniago</dc:creator>
      <pubDate>Sat, 01 Feb 2020 00:09:09 +0000</pubDate>
      <link>https://dev.to/diegopaniago/eventos-de-dominio-e-como-tornar-o-desacoplamento-algo-real-5e96</link>
      <guid>https://dev.to/diegopaniago/eventos-de-dominio-e-como-tornar-o-desacoplamento-algo-real-5e96</guid>
      <description>&lt;p&gt;Evento de domínio é uma tática abordada pelo Domain Driven Design(DDD) desde sempre, mas percebo que muitos desenvolvedores subestimam a capacidade que o evento de domínio tem de tornar o seu software menos acoplado, simples e de responsabilidades bem definidas.&lt;/p&gt;

&lt;p&gt;Alguns desenvolvedores chegam a dizer que é uma forma de trabalhar altamente complexa de ser implementada e que torna o software moroso para se trabalhar.&lt;/p&gt;

&lt;p&gt;Hoje eu venho mostrar como tudo isso pode ser implementado de maneira simples e cumprir as promessas acima.&lt;/p&gt;

&lt;p&gt;Um evento de domínio é a abstração de um acontecimento que tenha ocorrido. Ele sempre vai ser gerado e notificado através de um notificador de eventos que por sua vez vai "entregar" esse evento a os interessados em ouvi-lo, ou seja os manipuladores de eventos(listeners).&lt;/p&gt;

&lt;p&gt;Antes de continuar vou demonstrar cada um desses padrões mencionados para que você comece a ver como tudo isso é implementado e como pode ser usado na sua aplicação. Utilizaremos Java 8 e Spring Boot 2.2.2, o código completo esta no meu &lt;a href="//github.com/diegopaniago/eventos-de-dominio/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Vou usar como exemplo fictício um contexto responsável por gerir e persistir cadastros de pessoas.&lt;/p&gt;

&lt;p&gt;Esta é abstração de um evento de domínio onde irá carregar os dados que fizerem sentido para você. Recomendo que o momento da ocorrência sempre esteja presente nesta abstração para que consiga organizar cronologicamente os acontecimentos principalmente se eles forem parar em uma mensageiria.&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;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EventoDeDominio&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ApplicationEvent&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;LocalDateTime&lt;/span&gt; &lt;span class="n"&gt;data&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;EventoDeDominio&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;source&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;LocalDateTime&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&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="nc"&gt;LocalDateTime&lt;/span&gt; &lt;span class="nf"&gt;getData&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;data&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;Então o evento em si fica assim.&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;NomeDaPessoaAlterado&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;EventoDeDominio&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;String&lt;/span&gt; &lt;span class="n"&gt;nomeAntigo&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;String&lt;/span&gt; &lt;span class="n"&gt;nomeAtual&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;NomeDaPessoaAlterado&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;source&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;LocalDateTime&lt;/span&gt; &lt;span class="n"&gt;data&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;nomeAntigo&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;nomeAtual&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&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;nomeAntigo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nomeAntigo&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;nomeAtual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nomeAtual&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="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getNomeAntigo&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;nomeAntigo&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="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getNomeAtual&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;nomeAtual&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;Como estou usando o Spring Boot ele já me entrega &lt;strong&gt;pronta&lt;/strong&gt; uma implementação de um notificador de eventos que é a classe ApplicationEventPublisher. É principalmente quando falamos deste notificador onde começam as implementações complexas e muitas vezes com um pattern mais complexo que o outro sem necessidade. Usando este notificador na minha camada de aplicação, eu executo a ação de alterar uma pessoa, e se bem sucedida notifico o evento NomeDaPessoaAlterado.&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="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;AtualizaPessoa&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;PessoaRepositorio&lt;/span&gt; &lt;span class="n"&gt;pessoaRepositorio&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;ApplicationEventPublisher&lt;/span&gt; &lt;span class="n"&gt;applicationEventPublisher&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;public&lt;/span&gt; &lt;span class="nf"&gt;AtualizaPessoa&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PessoaRepositorio&lt;/span&gt; &lt;span class="n"&gt;pessoaRepositorio&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ApplicationEventPublisher&lt;/span&gt; &lt;span class="n"&gt;applicationEventPublisher&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;pessoaRepositorio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pessoaRepositorio&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;applicationEventPublisher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;applicationEventPublisher&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;atualizarNome&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PessoaDto&lt;/span&gt; &lt;span class="n"&gt;pessoaDto&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;Pessoa&lt;/span&gt; &lt;span class="n"&gt;pessoa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pessoaRepositorio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pessoaDto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&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="nc"&gt;NomeDaPessoaAlterado&lt;/span&gt; &lt;span class="n"&gt;nomeDaPessoaAlterado&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;NomeDaPessoaAlterado&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="nc"&gt;LocalDateTime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNome&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;pessoaDto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pessoa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;alterarNome&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pessoaDto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pessoaRepositorio&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="n"&gt;pessoa&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;applicationEventPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;publishEvent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nomeDaPessoaAlterado&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;A partir do momento que temos um evento notificado precisamos apenas criar o(s) manipulador(es) interessados neste evento na nossa camada de infra para que seja possível extrair as regras de negócio que não fazem parte da responsabilidade do serviço de alterar.&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="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;ManipuladorDeNomeDaPessoaAlterado&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ApplicationListener&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NomeDaPessoaAlterado&lt;/span&gt;&lt;span class="o"&gt;&amp;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;onApplicationEvent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;NomeDaPessoaAlterado&lt;/span&gt; &lt;span class="n"&gt;nomeDaPessoaAlterado&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;"Evento Pessoa alterada"&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="n"&gt;nomeDaPessoaAlterado&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getData&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&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="n"&gt;nomeDaPessoaAlterado&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNomeAntigo&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="n"&gt;nomeDaPessoaAlterado&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNomeAtual&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;A partir desse ponto eu desacoplo outras regras de negócio que cercam a ação de alterar uma Pessoa da responsabilidade única e exclusiva do serviço AtualizaPessoa de realizar o update da entidade Pessoa no banco.&lt;/p&gt;

&lt;p&gt;Eventos de domínio servem para tornar o seu código, infra e contexto simples e desacoplados. Eles permitem que complexidades referentes a &lt;strong&gt;outras regras de negócio&lt;/strong&gt; sejam implementadas em um outro momento, tornando o código da ação que esta sendo executada de &lt;strong&gt;responsabilidade única&lt;/strong&gt; e bem &lt;strong&gt;delimitada&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Como no exemplo acima, o comando do momento é apenas alterar os dados da Entidade Pessoa, se minha regra de negócio diz que devo por exemplo salvar o log do acontecimento ou atualizar outros dados de outras Entidades no momento que a alteração ocorrer, essas complexidades podem ser implementadas separadamente e consequentemente você vai ganhar desacoplamento, facilidade de testar, e melhor controle transacional(limite transacional).&lt;/p&gt;

&lt;p&gt;Essa tática permite que sua regra de negócio possa evoluir indefinidamente sem que a mera ação de alterar os dados de um cadastro, como no exemplo, exploda o tamanho do seu serviço de alteração, se ele é de alteração ele deve estritamente, unicamente, haja o que houver alterar o cadastro e nada mais.&lt;/p&gt;

&lt;p&gt;Para finalizar, outro benefício dessa abordagem é que ela permite começar a extrair um contexto de um sistema monolítico de forma gradual, de tal forma que aos poucos as regras de negócio referentes ao contexto que deseja extrair possam começar a serem executados em outro local.&lt;/p&gt;

</description>
      <category>ddd</category>
      <category>architecture</category>
      <category>java</category>
    </item>
  </channel>
</rss>
