<?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: Yan Justino</title>
    <description>The latest articles on DEV Community by Yan Justino (@yanjustino).</description>
    <link>https://dev.to/yanjustino</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%2F746597%2Fe0f26501-6c77-4c2b-bd8f-e3a3df1f08ae.jpeg</url>
      <title>DEV Community: Yan Justino</title>
      <link>https://dev.to/yanjustino</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yanjustino"/>
    <language>en</language>
    <item>
      <title>Classificação de Antipadrões em Microsserviços ‐ Parte 03</title>
      <dc:creator>Yan Justino</dc:creator>
      <pubDate>Thu, 09 May 2024 00:47:35 +0000</pubDate>
      <link>https://dev.to/yanjustino/classificacao-de-antipadroes-em-microsservicos-parte-03-fk4</link>
      <guid>https://dev.to/yanjustino/classificacao-de-antipadroes-em-microsservicos-parte-03-fk4</guid>
      <description>&lt;p&gt;&lt;strong&gt;YAN JUSTINO&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://repositorio.ufrn.br/handle/123456789/26370" rel="noopener noreferrer"&gt;MSc. Software Engineering&lt;/a&gt; · &lt;a href="https://www.cesar.school/doutorado-profissional-em-engenharia-de-software/" rel="noopener noreferrer"&gt;PhD. Student&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;AWS&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;MCSD&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;OCA&lt;/a&gt; · &lt;a href="https://orcid.org/0000-0001-7248-716X" rel="noopener noreferrer"&gt;ORCID&lt;/a&gt;  · &lt;a href=""&gt;Tech Lead at ITAÚ Unibanco&lt;/a&gt;&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%2Fimg.shields.io%2Fbadge%2Fpost-design-50A6C5%3Fstyle%3Dfor-the-badge" 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%2Fimg.shields.io%2Fbadge%2Fpost-design-50A6C5%3Fstyle%3Dfor-the-badge" alt="Static Badge"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. CONTEXTO
&lt;/h2&gt;

&lt;p&gt;Olá, Dev! Neste post listaremos um catálogo de antipadrões associados a implementação de Microsserviços. Esse catálogo contém uma breve descrição de cada antipadrão, os problemas que eles podem causar e as possíveis soluções que podem ser aplicadas para sanar possíveis problemas de design.&lt;/p&gt;

&lt;p&gt;Na &lt;a href="https://dev.to/yanjustino/classificacao-de-antipadroes-em-microsservicos-parte-01-27c9"&gt;parte 01&lt;/a&gt;, listamos 5 antipadrões do catálogo de antipadrões de microsserviços. Os antipadrões apresentados foram Wrong Cuts (WC); Cyclic Dependencies (CD); Mega Service (MS); Nano Service (NS); e Shared Librararies (SL).&lt;/p&gt;

&lt;p&gt;Já na &lt;a href="https://dev.to/yanjustino/classificacao-de-antipadroes-em-microsservicos-parte-02-4e92"&gt;parte 02&lt;/a&gt; aparesentamos quatro antipadrões: Multiple Service Instances Per Host (MSIPH); Shared Persistence (SP); No API Versioning (NAV); No API Gateway (NAG).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. ANTIPADRÕES
&lt;/h2&gt;

&lt;p&gt;Nesta terceira e última parte vamos abordar alguns &lt;em&gt;Antipatterns&lt;/em&gt; relacionados a monitoria de microsserviços. Eles são: No Health Check (NHC); Local Logging (LL); e Insufficient Monitoring (IM).&lt;/p&gt;




&lt;center&gt;
&lt;h3&gt;✍️ No Health Check (NHC)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Microsserviços são por natureza instáveis, podendo ser implementados em variados locais e ficarem indisponíveis temporariamente ou sob certas condições. Esse antipadrão ocorre quando não existe um endpoint disponível para avaliar o estado operacional do microsserviço. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;
 

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;A ausência de verificações de status regulares através de requisições HTTP, ou a falta de um gateway de API ou sistema de descoberta de serviços, podem sugerir esse antipadrão.&lt;/li&gt;
&lt;li&gt;Consumidores do microsserviço podem enfrentar atrasos ou falhas ao receber respostas se o microsserviço estiver fora do ar.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Incorporar endpoints de verificação de estado nos microsserviços que verifiquem periodicamente sua disponibilidade e capacidade de resposta&lt;/strong&gt;: Introduzindo endpoints de verificação de estado, microsserviços desativados não processarão requisições, e os consumidores serão informados sobre a indisponibilidade antes de fazerem suas solicitações. Isso evita atrasos e tempos de espera desnecessários.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://microservices.io/patterns/observability/health-check-api.html" rel="noopener noreferrer"&gt;Pattern: Health Check API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;center&gt;
&lt;h3&gt;✍️Local Logging (LL)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Cada microsserviço gera uma grande quantidade de informações que são registradas em sistemas de arquivos diferentes. Essas informações são extremamente úteis para monitoramento e devem ser acessíveis e armazenadas de maneira eficiente. Esse Antipadrão ocorre quando cada microsserviço registra suas informações em um armazenamento local. Indícios desse antipadrão incluem a presença de arquivos de log dentro dos microsserviços, arquivos sendo escritos pelo microsserviço, uso de bancos de dados conscientes de tempo e ferramentas e frameworks de registro.
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;
 

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Logs locais podem ser muito difíceis de agregar e analisar. Isso desacelera o processo de monitoramento proporcionalmente ao número de microsserviços e ao tamanho do log.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Implementar um sistema de registro distribuído que seja responsável por agregar os logs de todos os microsserviços&lt;/strong&gt;: Utilizar um mecanismo de registro distribuído permite ter um repositório único de logs, força os microsserviços a usar o mesmo formato de log e simplifica os processos de monitoramento e análise.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://microservices.io/patterns/observability/application-logging.html" rel="noopener noreferrer"&gt;Pattern: Log aggregation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;center&gt;
&lt;h3&gt;✍️ Insufficient Monitoring (IM)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Dado que os microsserviços fornecidos são frequentemente sujeitos a acordos de nível de serviço (SLA), monitorar seu comportamento e desempenho é crucial. Esse Antipadrão ocorre quando o desempenho e as falhas dos microsserviços não são rastreados. Algumas indicações desse antipadrão incluem o uso de registros locais para alguns microsserviços ou a ausência de endpoints de verificação de saúde.
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Um monitoramento insuficiente pode prejudicar as atividades de manutenção em um sistema baseado em microsserviços. Falhas tornam-se mais difíceis de detectar e rastrear problemas de desempenho torna-se mais tedioso. Isso pode até afetar a capacidade de cumprir com o SLA.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Utilizar uma ferramenta de monitoramento que colete dados de desempenho e estatísticas de falhas de cada microsserviço no sistema&lt;/strong&gt;: Monitorar todos os aspectos de um sistema baseado em microsserviços fornece uma compreensão completa do comportamento da aplicação. Ele também fornece dados que podem ser usados para melhorar o desempenho e a qualidade de toda a aplicação.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a&gt;observability&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. CONCLUSÃO
&lt;/h2&gt;

&lt;p&gt;Nesse post listamos alguns antipadrões associados a microsserviços. Cada antipadrões de microsserviços aponta para desafios comuns que podem comprometer a eficiência, escalabilidade e manutenibilidade de arquiteturas baseadas em microsserviços. &lt;/p&gt;

&lt;p&gt;Desde problemas de design, como dependências cíclicas e serviços excessivamente grandes ou pequenos, até questões operacionais como configuração manual, falta de integração e entrega contínuas, e monitoramento insuficiente, cada antipadrão destaca uma área crítica onde as práticas inadequadas podem levar a falhas sistêmicas e degradar a qualidade do serviço. &lt;/p&gt;

&lt;p&gt;Reconhecer e refatorar esses antipadrões é essencial para maximizar os benefícios de uma arquitetura de microsserviços, garantindo que eles permaneçam robustos, ágeis e capazes de atender às demandas dinâmicas dos ambientes de TI modernos.&lt;/p&gt;

&lt;h4&gt;
  
  
  ATENÇÃO!!!
&lt;/h4&gt;

&lt;p&gt;Os artigos referenciados possuem outros antipadrões não abordados nesse post. Recomendo fortemente sua leitura.&lt;/p&gt;

&lt;h2&gt;
  
  
  REFERÊNCIAS
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;MENDONCA, N. C. et al. The monolith strikes back: Why istio migrated from&lt;br&gt;
microservices to a monolithic architecture. IEEE Software, Institute of Electrical and&lt;br&gt;
Electronics Engineers (IEEE), v. 38, n. 5, p. 17–22, set. 2021. ISSN 1937-4194.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BOGNER, J. et al. Industry practices and challenges for the evolvability assurance of&lt;br&gt;
microservices: An interview study and systematic grey literature review. Empirical&lt;br&gt;
Software Engineering, Springer Science and Business Media LLC, v. 26, n. 5, jul. 2021.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FORD, N. Software architecture: The hard parts : modern trade-off analyses for&lt;br&gt;
distributed architectures. First edition. Cambridge, Massachusetts: The MIT Press, 2021.&lt;br&gt;
Made available through: Safari, an O’Reilly Media Company. ISBN 1492086843.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NEWMAN, S. Building microservices: Designing fine-grained systems. Second edition.&lt;br&gt;
Beijing: O’Reilly, 2021. ISBN 9781492033998.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tighilt, R., Abdellatif, M., Trabelsi, I., Madern, L., Moha,&lt;br&gt;
N., and Guéhéneuc, Y.-G. (2023). On the maintenance&lt;br&gt;
support for microservice-based systems through the&lt;br&gt;
specification and the detection of microservice antipatterns.&lt;br&gt;
Journal of Systems and Software, 204:111755. DOI:&lt;br&gt;
&lt;a href="https://doi.org/10.1016/j.jss.2023.111755" rel="noopener noreferrer"&gt;https://doi.org/10.1016/j.jss.2023.111755&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Taibi, D. and Lenarduzzi, V. (2018). On the definition of microservice&lt;br&gt;
bad smells. IEEE Software, 35(3):56–62. DOI:&lt;br&gt;
10.1109/MS.2018.2141031.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Caro leitor,
&lt;/h2&gt;

&lt;p&gt;Espero que tenham encontrado insights valiosos na discussão sobre a co-localização de arquivos de teste e código de produção, uma prática que pode transformar significativamente o desenvolvimento de software.&lt;/p&gt;

&lt;p&gt;Se você já experimentou essa metodologia em seus projetos, como foi? Quais vantagens e obstáculos você encontrou? Se ainda não tentou, consideraria implementá-la após essa leitura?&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>architecture</category>
      <category>microservices</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Classificação de Antipadrões em Microsserviços ‐ Parte 02</title>
      <dc:creator>Yan Justino</dc:creator>
      <pubDate>Wed, 01 May 2024 01:56:40 +0000</pubDate>
      <link>https://dev.to/yanjustino/classificacao-de-antipadroes-em-microsservicos-parte-02-4e92</link>
      <guid>https://dev.to/yanjustino/classificacao-de-antipadroes-em-microsservicos-parte-02-4e92</guid>
      <description>&lt;p&gt;&lt;strong&gt;YAN JUSTINO&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://repositorio.ufrn.br/handle/123456789/26370"&gt;MSc. Software Engineering&lt;/a&gt; · &lt;a href="https://www.cesar.school/doutorado-profissional-em-engenharia-de-software/"&gt;PhD. Student&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youracclaim.com/users/yan-justino/badges"&gt;AWS&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges"&gt;MCSD&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges"&gt;OCA&lt;/a&gt; · &lt;a href="https://orcid.org/0000-0001-7248-716X"&gt;ORCID&lt;/a&gt;  · &lt;a href=""&gt;Tech Lead at ITAÚ Unibanco&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zARs327v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/post-design-50A6C5%3Fstyle%3Dfor-the-badge" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zARs327v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/post-design-50A6C5%3Fstyle%3Dfor-the-badge" alt="Static Badge" width="131" height="28"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. CONTEXTO
&lt;/h2&gt;

&lt;p&gt;Olá, Dev! Neste post estamos listando um catálogo de antipadrões associados a implementação de Microsserviços. Esse catálogo contém uma breve descrição de cada antipadrão, os problemas que eles podem causar e as possíveis soluções que podem ser aplicadas para sanar possíveis problemas de design.&lt;/p&gt;

&lt;p&gt;Na &lt;a href="https://dev.to/yanjustino/classificacao-de-antipadroes-em-microsservicos-parte-01-27c9"&gt;primeira parte&lt;/a&gt;, listamos 5 antipadrões do catálogo de antipadrões de microsserviços apresentado pelos pesquisadores &lt;strong&gt;Taibi, D. and Lenarduzzi, V. (2018)&lt;/strong&gt;[6] e &lt;strong&gt;Tighilt at al (2023)&lt;/strong&gt;[5]. Os antipadrões apresentados foram Wrong Cuts (WC); Cyclic Dependencies (CD); Mega Service (MS); Nano Service (NS); e Shared Librararies (SL). &lt;/p&gt;

&lt;h2&gt;
  
  
  2. ANTIPADRÕES
&lt;/h2&gt;

&lt;p&gt;Nesta parte 02 apresentaremos os antipadrões Multiple Service Instances Per Host (MSIPH); Shared Persistence (SP); No API Versioning (NAV); No API Gateway (NAG).&lt;/p&gt;




&lt;center&gt;
&lt;h3&gt;✍️ Multiple Service Instances Per Host (MSIPH)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Acontece quando vários microsserviços são implantados em um único host, que pode ser um container, uma máquina física ou uma máquina virtual. Isso pode parecer conveniente ou eficiente em termos de utilização de recursos, mas traz consigo uma série de desvantagens significativas que podem afetar negativamente a arquitetura e a operação de um sistema baseado em microsserviços. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;
 

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Impacto na autonomia&lt;/strong&gt;: com o antipadrão MSIPH, a autonomia é comprometida, pois a falha de um serviço no host pode impactar outros serviços compartilhando o mesmo ambiente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Impacto na Escala&lt;/strong&gt;: no contexto do MSIPH, a escalabilidade é afetada, pois escalar um serviço pode exigir mais recursos do host, potencialmente afetando o desempenho de outros serviços que compartilham o mesmo ambiente&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Possíveis conflitos dentro do host&lt;/strong&gt;: Com múltiplos serviços compartilhando o mesmo host, há um risco aumentado de conflitos de recursos, como uso de CPU, memória e I/O. .
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;p&gt;Para evitar os problemas associados ao MSIPH, é recomendável adotar estratégias como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Containerização&lt;/strong&gt;: Utilizar containers para encapsular cada serviço individualmente, garantindo que eles operem em ambientes isolados mesmo quando implantados na mesma máquina física ou virtual.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Orquestração de Containers&lt;/strong&gt;: Usar sistemas de orquestração, como Kubernetes, que gerenciam a implantação, escalonamento e operação de containers de forma eficiente, garantindo que os serviços não interfiram uns com os outros.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Escalonamento Dinâmico&lt;/strong&gt;: Implementar políticas de escalonamento automático que permitam que cada serviço escale baseado em suas próprias demandas de recursos, sem afetar outros serviços.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitoramento e Gerenciamento de Recursos&lt;/strong&gt;: Adotar ferramentas avançadas de monitoramento e gerenciamento de recursos para detectar e mitigar problemas de contenção de recursos rapidamente.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://microservices.io/patterns/deployment/multiple-services-per-host.html"&gt;Multiple service instances per host&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dzone.com/articles/microservices-deployment-patterns"&gt;Microservices Deployment Patterns&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;center&gt;
&lt;h3&gt;✍️ Shared Persistence (SP)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Acontece quando vários microsserviços acessam o mesmo banco de dados relacional. No pior dos cenár.ios, diferentes serviços acessam a mesma entidade do mesmo banco de dados. Um Microsserviço deve ser dono apenas dos dados que ele precisa. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;
 

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Acoplamento via banco de dados&lt;/li&gt;
&lt;li&gt;Diminuição da autonomia da equipe e do serviço&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;p&gt;Isso antipadrão pode levar a uma série de problemas, principalmente relacionados ao acoplamento e à perda de autonomia, como mecionado. Aqui estão algumas das principais soluções para superar este antipadrão:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bancos de Dados Independentes&lt;/strong&gt;: A solução mais alinhada com os princípios de microsserviços é que cada serviço tenha seu próprio banco de dados, garantindo assim a total autonomia dos dados. Isso reduz o acoplamento e permite que cada equipe seja responsável por sua parte da infraestrutura de dados, facilitando escalabilidade e manutenção.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Banco Compartilhado com Tabelas Privadas&lt;/strong&gt;:&lt;br&gt;
Uma alternativa menos isolada, mas ainda viável, é utilizar um banco de dados compartilhado onde cada serviço tem seu próprio conjunto de tabelas. Essas tabelas não são acessíveis por outros serviços, o que ajuda a manter certo grau de isolamento e controle sobre os dados.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Uso de Esquemas de Banco de Dados&lt;/strong&gt;: &lt;br&gt;
Outra abordagem é o uso de esquemas dentro de um banco de dados compartilhado, onde cada esquema é dedicado a um microsserviço específico. Isso ajuda a manter o isolamento lógico dentro de um mesmo banco de dados físico, facilitando a gestão de permissões e visibilidade de dados.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integradores de granularidade&lt;/strong&gt;:&lt;br&gt;
Para casos em que a granularidade vá contra a integridade de dados em um processo que deveria ser transacionalmente simples, a equipe pode deliberar sobre a doção de estratégias integradoras de granularidade.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/modernization-data-persistence/shared-database.html"&gt;Shared-database-per-service pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://microservices.io/patterns/data/shared-database.html"&gt;Shared database&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;center&gt;
&lt;h3&gt;✍️ No API Gateway (NAG)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Ocorre quando uma arquitetura de microsserviços é implementada sem um API Gateway, levando a que os clientes tenham que interagir diretamente com os microsserviços individuais. Esse antipadrão pode trazer vários problemas e desafios, especialmente em ambientes de produção com várias interfaces de serviço. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;
 

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Complexidade para os Clientes&lt;/strong&gt;: Sem um API Gateway, os clientes precisam conhecer e gerenciar os pontos de acesso de todos os microsserviços que precisam consumir, aumentando a complexidade do lado do cliente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dificuldades de Autenticação e Autorização&lt;/strong&gt;: Cada serviço pode precisar implementar seu próprio mecanismo de autenticação e autorização, o que pode levar a inconsistências e brechas de segurança.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gestão de Carga e Falhas&lt;/strong&gt;: Em uma configuração NAG, a lógica para balanceamento de carga e tratamento de falhas pode precisar ser implementada em cada serviço ou no lado do cliente, o que pode complicar o desenvolvimento e a manutenção.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versionamento de APIs&lt;/strong&gt;: Gerenciar diferentes versões de API diretamente nos serviços pode tornar-se problemático, especialmente em um ambiente com muitos serviços que evoluem rapidamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;p&gt;Implementar um API Gateway é uma prática comum em arquiteturas de microsserviços modernas devido às suas vantagens em simplificar a gestão de APIs, segurança, e resiliência. Ferramentas populares para este propósito incluem Kong, Apigee e AWS API Gateway, cada uma oferecendo conjuntos robustos de funcionalidades para lidar com as necessidades complexas de microsserviços em ambientes de produção.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implementação de um API Gateway:&lt;/strong&gt; A solução mais direta para o antipadrão NAG é introduzir um API Gateway na arquitetura. O API Gateway atua como um ponto de entrada único para todas as chamadas de API, simplificando a interação do cliente com os microsserviços.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centralização de Autenticação e Autorização:&lt;/strong&gt; Com um API Gateway, é possível centralizar processos de autenticação e autorização, proporcionando um mecanismo consistente e seguro para controlar o acesso aos serviços.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Balanceamento de Carga e Resiliência:&lt;/strong&gt; O API Gateway pode gerenciar o balanceamento de carga e implementar padrões de resiliência, como circuit breakers e retries, para lidar com falhas nos serviços de forma transparente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gestão de Tráfego e Versionamento:&lt;/strong&gt; O Gateway permite a gestão eficiente do tráfego e facilita a implementação de estratégias de versionamento de API, permitindo que diferentes versões de serviços sejam acessadas sem impactar os clientes existentes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.developer.com/design/solving-microservices-anti-patterns/"&gt;Overcoming the Common Microservices Anti-Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://smartbear.com/learn/api-design/api-gateways-in-microservices/"&gt;Using an API Gateway in Your Microservices Architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;center&gt;
&lt;h3&gt;✍️ No API Versioning (NAV)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Refere-se a uma falha de design no desenvolvimento de software onde uma interface de programação de aplicações (API) não é projetada para suportar múltiplas versões simultaneamente. Isso pode criar problemas significativos ao longo do tempo à medida que as APIs evoluem. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mudanças Que Quebram a Compatibilidade:&lt;/strong&gt; Sem versionamento, qualquer atualização ou modificação pode potencialmente quebrar as aplicações existentes que dependem da API, levando a malfuncionamentos de software e interrupções no serviço.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dificuldade na Manutenção:&lt;/strong&gt; A falta de versionamento torna desafiador manter a compatibilidade com versões anteriores, forçando os clientes a se adaptarem rapidamente às mudanças ou enfrentarem problemas de incompatibilidade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Barreiras à Adoção:&lt;/strong&gt; Novos usuários podem hesitar em adotar a API se perceberem que ela muda frequentemente sem um gerenciamento claro de versões, pois isso pode implicar em custos de manutenção mais altos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;p&gt;Abordar o antipadrão NAV é crucial para garantir que as APIs permaneçam robustas, confiáveis e fáceis de usar, melhorando assim a sustentabilidade geral dos sistemas de software. Os itens a seguir podem auxiliar a lidar com os problemas listados anteriormente.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implementar Estratégia de Versionamento:&lt;/strong&gt; Introduza uma estratégia sistemática de versionamento, como o Versionamento Semântico (SemVer), onde as versões são incrementadas com base na natureza das alterações (maior, menor, correção) para comunicar claramente o impacto das atualizações.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Política de Depreciação de Versões:&lt;/strong&gt; Estabeleça uma política clara de depreciação para versões antigas, fornecendo aos usuários bastante aviso e orientação sobre a transição para versões mais novas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Suportar Múltiplas Versões:&lt;/strong&gt; Mantenha suporte para múltiplas versões de API simultaneamente para permitir que os usuários façam a transição em seu próprio ritmo sem interromper seus sistemas atuais. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ieeexplore.ieee.org/document/9556611"&gt;A Mixed-Method Approach to Recommend Corrections and Correct REST Antipatterns&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  REFERÊNCIAS
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;MENDONCA, N. C. et al. The monolith strikes back: Why istio migrated from&lt;br&gt;
microservices to a monolithic architecture. IEEE Software, Institute of Electrical and&lt;br&gt;
Electronics Engineers (IEEE), v. 38, n. 5, p. 17–22, set. 2021. ISSN 1937-4194.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BOGNER, J. et al. Industry practices and challenges for the evolvability assurance of&lt;br&gt;
microservices: An interview study and systematic grey literature review. Empirical&lt;br&gt;
Software Engineering, Springer Science and Business Media LLC, v. 26, n. 5, jul. 2021.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FORD, N. Software architecture: The hard parts : modern trade-off analyses for&lt;br&gt;
distributed architectures. First edition. Cambridge, Massachusetts: The MIT Press, 2021.&lt;br&gt;
Made available through: Safari, an O’Reilly Media Company. ISBN 1492086843.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NEWMAN, S. Building microservices: Designing fine-grained systems. Second edition.&lt;br&gt;
Beijing: O’Reilly, 2021. ISBN 9781492033998.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tighilt, R., Abdellatif, M., Trabelsi, I., Madern, L., Moha,&lt;br&gt;
N., and Guéhéneuc, Y.-G. (2023). On the maintenance&lt;br&gt;
support for microservice-based systems through the&lt;br&gt;
specification and the detection of microservice antipatterns.&lt;br&gt;
Journal of Systems and Software, 204:111755. DOI:&lt;br&gt;
&lt;a href="https://doi.org/10.1016/j.jss.2023.111755"&gt;https://doi.org/10.1016/j.jss.2023.111755&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Taibi, D. and Lenarduzzi, V. (2018). On the definition of microservice&lt;br&gt;
bad smells. IEEE Software, 35(3):56–62. DOI:&lt;br&gt;
10.1109/MS.2018.2141031.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Caros leitores,
&lt;/h2&gt;

&lt;p&gt;Espero que tenham encontrado insights valiosos na discussão sobre a co-localização de arquivos de teste e código de produção, uma prática que pode transformar significativamente o desenvolvimento de software.&lt;/p&gt;

&lt;p&gt;Se você já experimentou essa metodologia em seus projetos, como foi? Quais vantagens e obstáculos você encontrou? Se ainda não tentou, consideraria implementá-la após essa leitura?&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>architecture</category>
      <category>microservices</category>
      <category>antippaterns</category>
    </item>
    <item>
      <title>Classificação de Antipadrões em Microsserviços ‐ Parte 01</title>
      <dc:creator>Yan Justino</dc:creator>
      <pubDate>Sat, 27 Apr 2024 18:20:15 +0000</pubDate>
      <link>https://dev.to/yanjustino/classificacao-de-antipadroes-em-microsservicos-parte-01-27c9</link>
      <guid>https://dev.to/yanjustino/classificacao-de-antipadroes-em-microsservicos-parte-01-27c9</guid>
      <description>&lt;p&gt;&lt;strong&gt;YAN JUSTINO&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://repositorio.ufrn.br/handle/123456789/26370" rel="noopener noreferrer"&gt;MSc. Software Engineering&lt;/a&gt; · &lt;a href="https://www.cesar.school/doutorado-profissional-em-engenharia-de-software/" rel="noopener noreferrer"&gt;PhD. Student&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;AWS&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;MCSD&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;OCA&lt;/a&gt; · &lt;a href="https://orcid.org/0000-0001-7248-716X" rel="noopener noreferrer"&gt;ORCID&lt;/a&gt;  · &lt;a href=""&gt;Tech Lead at ITAÚ Unibanco&lt;/a&gt;&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%2Fimg.shields.io%2Fbadge%2Fpost-design-50A6C5%3Fstyle%3Dfor-the-badge" 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%2Fimg.shields.io%2Fbadge%2Fpost-design-50A6C5%3Fstyle%3Dfor-the-badge" alt="Static Badge"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. CONTEXTO
&lt;/h2&gt;

&lt;p&gt;Microsserviços tornou-se uma prática no design, construção e entrega de serviços de software baseados em &lt;em&gt;Cloud Computing&lt;/em&gt;.&lt;br&gt;
Impulsionada por grandes companhias de tecnologia como Amazon, Netflix e Spotify etc, a Arquitetura de Microsserviços tem sido considerada uma abordagem desejada por startups, pequenas empresas e organizações que cresceram na ordem de centenas de engenheiros. A transição para essa abordagem arquitetural é motivada pela crescente necessidade de escala, robustez dos sistemas, diversificação na adoção de tecnologia e aprimoramentos do paralelismo no desenvolvimento de software. &lt;/p&gt;

&lt;p&gt;Ao migrar para Microsserviços, empresas têm buscado uma melhor qualidade de Desempenho, Escalabilidade e Manutenibilidade por meio da decomposição e distribuição de seus sistemas monolíticos em partes que são fáceis de compreender e de manter.&lt;br&gt;
Relatos recentes da indústria têm apresentado diversos casos nos quais equipes de desenvolvimento de software conduziram um processo de reengenharia adotando a Arquitetura de Microsserviços como estratégia de modernização de seus sistemas.&lt;/p&gt;

&lt;p&gt;Esses casos revelam que equipes que passam por esse difícil processo, precisam definir qual o nível de granularidade consegue administrar, levando em consideração as necessidades específicas do projeto. Esse passo é importante pois, uma vez o sistema migrado, a equipe precisará lidar com uma série de desafios técnicos como a garantia de disponibilidade; operações transacionais em um sistema distribuído; o aumento da latência; a tolerância a falhas de comunicação entre serviços; o controle de versão; a gestão de uma grande quantidade de recursos e automações etc.&lt;/p&gt;

&lt;p&gt;Contudo, determinar uma clara definição de fronteiras na concepção de um Microsserviço tem sido apontado como um dos principais desafios por equipes de desenvolvimento. Isso porque, decompor um sistema e tentar definir “corretamente” sua granularidade, além de ser uma tarefa complexa e extremamente contextual, pode impactar diretamente o uso de recursos computacionais e os atributos de qualidade da aplicação. Nesse contexto, e considerando as vastas interpretações possíveis dos conceitos ligados a Microsserviços, é possível que equipes de desenvolvimento modelem ou construam soluções baseando-se em antipadrões (&lt;em&gt;antipatterns&lt;/em&gt; - conhecidos e recorrentes problemas de design). &lt;/p&gt;

&lt;p&gt;Investigando os processos de migração para Microsserviços e analisando os resultados alcançados, pesquisadores da França e Canadá [5] apresentaram um catálogo de vários antipadrões de microsserviços, construído através de uma revisão sistemática da literatura, que identificou mais 1.195 artigos através de uma consulta nas principais bases de dados científicas. Nessa mesma linha, uma dupla de pesquisadores filandeses [6] coletaram evidências de más práticas entrevistando 72 profissionais com experiência no desenvolvimento de sistemas baseados em microsserviços.&lt;/p&gt;

&lt;p&gt;Com base nessas pesquisas, listaremos um catálogo de antipadrões contendo uma breve descrição de cada um deles, as consequências de sua adoção e possíveis soluções que podem ser aplicadas.  &lt;/p&gt;

&lt;h2&gt;
  
  
  2. ANTIPADRÕES
&lt;/h2&gt;

&lt;p&gt;Dado o número de itens desse catálogo, dividiremos o conteúdo desse artigo em 3 partes. Na parte 01 exploraremos os antipadrões: Wrong Cuts (WC); Cyclic Dependencies (CD); Mega Service (MS); Nano Service (NS); e Shared Librararies (SL).&lt;/p&gt;




&lt;center&gt;
&lt;h3&gt;✍️ Wrong Cuts (WC)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Equipes de software tendem a priorizar aspectos de runtime (desempenho e escala) e infraestrutura quando segmentam uma capacidade de negócio em serviços. Essa abordagem pode ser precoce e impactar a qualidade do sistema. Nesse contexto, esse antipadrão ocorre quando microsserviços são divididos com base em camadas técnicas (Presentation, Business e Data) em vez de uma divisão por capacidade de negócio. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Problemas na separação de responsabilidades&lt;/li&gt;
&lt;li&gt;Aumento da complexidade na divisão de dados
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;p&gt;A adoção de métodos de modelagem, como &lt;em&gt;Domain-Driven Design&lt;/em&gt; (DDD) e &lt;em&gt;Business Capability Analysis&lt;/em&gt;, somados a adoção de métodos de avaliação arquitetural, como o &lt;em&gt;Architectural Trade-off Analysis Method&lt;/em&gt; (ATAM) são apontados como estratégias para auxiliar às equipes, ainda nas fases iniciais do projeto, na identificação de possíveis fronteiras de negócio e na validação da proposta arquitetural do sistema.&lt;/p&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Para entender os tipos de design e organização do código sugiro a leitura do post &lt;a href="https://dev.to/yanjustino/alem-dos-templates-uma-critica-construtiva-a-arquitetura-limpa-e-a-adaptacao-pragmatica-no-design-de-software-1l2"&gt;Além dos Templates: Uma Crítica Construtiva à Arquitetura Limpa e a Adaptação Pragmática no Design de Software&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;center&gt;
&lt;h3&gt;✍️ Cyclic Dependencies (CD)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Esse antipadrão ocorre quando múltiplos serviços são circularmante co-dependente e não autônomos, o que vai de encontro diretamente a definição de Microsserviço. Isso pode ser detectado pela existência de chamada circulares entre microsserviços. Por exemplo, A chama B, B chama C, e C chama de volta A. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Dificuldades na manutenção do sistema&lt;/li&gt;
&lt;li&gt;Problemans no reuso e isolamento de software &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;p&gt;Realizar revisão e refinamento das formas de relação entre serviços. Recomenda-se a adoção de &lt;em&gt;API Gateway&lt;/em&gt; e &lt;em&gt;Service Mesh&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LEITURAS RECOMENDADAS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://engsoftmoderna.info/faq/padroes-faq.html#qual-a-diferen%C3%A7a-entre-uma-fachada-e-um-api-gateway" rel="noopener noreferrer"&gt;Qual a diferença entre uma Fachada e um API Gateway?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Esse vídeo do José Roberto Araújo da Emergin Code demonstra a &lt;a href="https://www.youtube.com/watch?v=Rx4YXkrAXD0" rel="noopener noreferrer"&gt;Implementanto AGREGAÇÃO em um API GATEWAY usando OCELOT&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;center&gt;
&lt;h3&gt;✍️ Mega Service (MS)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Esse antipadrão ocorre quando um microsserviço fornece multiplas capacidades de negócio. Um serviço que possui um número excessivo de responsabilidades de negócio deveria ser decomposto. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Alto acoplamento&lt;/li&gt;
&lt;li&gt;Dificuldades na escala do serviço &lt;/li&gt;
&lt;li&gt;Dificuldades na manutenção do sistema&lt;/li&gt;
&lt;li&gt;Coordenação excessiva entre equipes&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;p&gt;Realizar a decomposição funcional do serviço que possui um número excessivo de responsabilidades de negócio.&lt;/p&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.infoq.com/br/articles/microservices-intro/" rel="noopener noreferrer"&gt;Microservices: Decomposição de Aplicações para Implantação e Escalabilidade&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/monolith-to-microservices/9781492047834/" rel="noopener noreferrer"&gt;Monolith to Microservices: Evolutionary Patterns to Transform Your Monolith.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;center&gt;
&lt;h3&gt;✍️ Nano Service (NS)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Ao contrário do Mega Service, esse antipadrão resulta de uma decomposição de um sistema em uma granularidade muito fina. Isso pode ocorrer quando uma unica capacidade de negócio requer muitos microsserviços trabalhando juntos. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;

&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Dificuldades na manutenção do sistema&lt;/li&gt;
&lt;li&gt;Explosão no número de componentes&lt;/li&gt;
&lt;li&gt;Aumento da complexidade do sistema&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;p&gt;Afim de evitar uma “explosão” no número de componentes no sistema, equipes devem ponderar se novos Microsserviços são de fato necessários. Nesse sentido, equipes podem considerar a adoção de estratégias como Monolitch first aproach ou Coarse-grained Microsserviço. Em caso de gargalos de desempenho em serviços já decompostos, ou em que a adoção de Microsserviço não trouxe os benefícios esperados, a equipe pode deliberar sobre a doção de estratégias integradoras de granularidade [Ford et al., 2021] e seguir por uma abordagem “Monolith Strikes Back” [Mendonça et al., 2021].&lt;/p&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.researchgate.net/publication/351248643_The_Monolith_Strikes_Back_Why_Istio_Migrated_From_Microservices_to_a_Monolithic_Architecture" rel="noopener noreferrer"&gt;The Monolith Strikes Back: Why Istio Migrated From Microservices to a Monolithic Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.primevideotech.com/video-streaming/scaling-up-the-prime-video-audio-video-monitoring-service-and-reducing-costs-by-90" rel="noopener noreferrer"&gt;Scaling up the Prime Video audio/video monitoring service and reducing costs by 90%&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;center&gt;
&lt;h3&gt;✍️ Shared Libraries (SL)&lt;/h3&gt;
&lt;br&gt;
&lt;small&gt;
Esse antipadrão ocorre quando múltiplos microsserviços compartilham bibliotecas e arquivos e esse compartilhamento quebra a autonomia da equipe, fazendo com que ela dependa de uma única fonte para cumprir sua capacidade de negócio. 
&lt;/small&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/center&gt;



&lt;h4&gt;
  
  
  PROBLEMAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Acoplamentos excessivos&lt;/li&gt;
&lt;li&gt;Coordenação e dependência entre equipes&lt;/li&gt;
&lt;li&gt;Controle de dependências mais rigoroso&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SOLUÇÃO
&lt;/h4&gt;

&lt;p&gt;Para obter os benefícios do reuso de software, equipes podem ter que lidar com o compartilhamento software através de monorepos, bibliotecas ou a redundância de código clonados em repositórios distintos. Nesse contexto, equipes devem controlar essa redundância e lidar com a necessidade de uma maior coordenação e dependência entre elas. Uma forma de monitorar esse reuso é a adoção de automações para identificação e quantificar a taxa de crescimento de duplicação de código. Uma possibilidade para lidar com o reuso de software é a extração do código duplicado como um serviço autônomo.&lt;/p&gt;

&lt;h4&gt;
  
  
  LEITURAS RECOMENDADAS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/microservices-antipatterns-and/9781492042716/ch03.html" rel="noopener noreferrer"&gt;The “I Was Taught to Share” AntiPattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Obrigado por ler o post. Nos próximos posts iremos explorar os demais antipadrões.&lt;/p&gt;

&lt;h2&gt;
  
  
  REFERÊNCIAS
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;MENDONCA, N. C. et al. The monolith strikes back: Why istio migrated from&lt;br&gt;
microservices to a monolithic architecture. IEEE Software, Institute of Electrical and&lt;br&gt;
Electronics Engineers (IEEE), v. 38, n. 5, p. 17–22, set. 2021. ISSN 1937-4194.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BOGNER, J. et al. Industry practices and challenges for the evolvability assurance of&lt;br&gt;
microservices: An interview study and systematic grey literature review. Empirical&lt;br&gt;
Software Engineering, Springer Science and Business Media LLC, v. 26, n. 5, jul. 2021.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FORD, N. Software architecture: The hard parts : modern trade-off analyses for&lt;br&gt;
distributed architectures. First edition. Cambridge, Massachusetts: The MIT Press, 2021.&lt;br&gt;
Made available through: Safari, an O’Reilly Media Company. ISBN 1492086843.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NEWMAN, S. Building microservices: Designing fine-grained systems. Second edition.&lt;br&gt;
Beijing: O’Reilly, 2021. ISBN 9781492033998.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tighilt, R., Abdellatif, M., Trabelsi, I., Madern, L., Moha,&lt;br&gt;
N., and Guéhéneuc, Y.-G. (2023). On the maintenance&lt;br&gt;
support for microservice-based systems through the&lt;br&gt;
specification and the detection of microservice antipatterns.&lt;br&gt;
Journal of Systems and Software, 204:111755. DOI:&lt;br&gt;
&lt;a href="https://doi.org/10.1016/j.jss.2023.111755" rel="noopener noreferrer"&gt;https://doi.org/10.1016/j.jss.2023.111755&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Taibi, D. and Lenarduzzi, V. (2018). On the definition of microservice&lt;br&gt;
bad smells. IEEE Software, 35(3):56–62. DOI:&lt;br&gt;
10.1109/MS.2018.2141031.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Continua...&lt;/p&gt;




&lt;h2&gt;
  
  
  Caros leitores,
&lt;/h2&gt;

&lt;p&gt;Espero que tenham encontrado insights valiosos na discussão sobre microsserviços e práticas que podem transformar significativamente o desenvolvimento de software.&lt;/p&gt;

&lt;p&gt;Você já conhecia esses antipadrões? Identificou algum deles em seu projeto? Deixe seu comentário&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Do Conceito à Codificação: Transformando Regras de Negócio em Códigos Confiáveis</title>
      <dc:creator>Yan Justino</dc:creator>
      <pubDate>Thu, 07 Mar 2024 02:51:09 +0000</pubDate>
      <link>https://dev.to/yanjustino/do-conceito-a-codificacao-transformando-regras-de-negocio-em-codigos-confiaveis-46ce</link>
      <guid>https://dev.to/yanjustino/do-conceito-a-codificacao-transformando-regras-de-negocio-em-codigos-confiaveis-46ce</guid>
      <description>&lt;p&gt;&lt;strong&gt;YAN JUSTINO&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://repositorio.ufrn.br/handle/123456789/26370" rel="noopener noreferrer"&gt;MSc. Software Engineering&lt;/a&gt; · &lt;a href="https://www.cesar.school/doutorado-profissional-em-engenharia-de-software/" rel="noopener noreferrer"&gt;PhD. Student&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;AWS&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;MCSD&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;OCA&lt;/a&gt; · &lt;a href="https://orcid.org/0000-0001-7248-716X" rel="noopener noreferrer"&gt;ORCID&lt;/a&gt;  · &lt;a href=""&gt;Tech Lead at ITAÚ Unibanco&lt;/a&gt;&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%2Fimg.shields.io%2Fbadge%2Fpost-design-50A6C5%3Fstyle%3Dfor-the-badge" 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%2Fimg.shields.io%2Fbadge%2Fpost-design-50A6C5%3Fstyle%3Dfor-the-badge" alt="Static Badge"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;As fronteiras da minha linguagem são as fronteiras do meu universo - &lt;strong&gt;Ludwig Wittgenstein&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  CONTEXTO
&lt;/h2&gt;

&lt;p&gt;A engenharia de software pode empregar muito esforço para alcançar uma clara definição de fronteiras de um sistema. Parte desse trabalho está na concepção de módulos, componentes e seus conectores, bem como as estruturas de alocação que satisfazem um conjunto de requisitos que, mediante determinadas expectativas de qualidade, respondem às demandas do negócio.&lt;/p&gt;

&lt;p&gt;Em colaboração com especialitas de negócio, o papel do desenvolvimento é "preencher" as lacunas dessas estruturas de software com comportamentos (ricos) do domínio. Para isso, equipes de desenvolvimento adotam métodos como &lt;em&gt;Business Process Management&lt;/em&gt; (BPM), &lt;em&gt;Domain-Driven Design&lt;/em&gt; (DDD), &lt;em&gt;Business Capability Analysis&lt;/em&gt; etc, para representar contextos do domínio e expressar regras negócio.&lt;/p&gt;

&lt;p&gt;Regras de negócio são as diretrizes, critérios, ou condições definidas dentro de uma organização para governar seus processos, operações e transações. Elas abrangem uma ampla gama de áreas podem especificar: critérios de elegibilidade, políticas, processos, padrões etc. Frequentemente regas de negócio são implementadas em sistemas de informação. Esse tipo de automatização permite um monitoramente eficiente dessas regras no cotidiando operacional das organizações.&lt;/p&gt;

&lt;p&gt;No entanto, a automatização de regras de negócio em sistemas de informação também demanda um nível de qualidade que garanta confiabilidade nas operações. Nesse sentido, é importante que desenvolvedores implementem os comportamentos de negócio de forma adequada ao ponto de serem livres de efeitos colaterais e fáceis de manter. Caso contrário, o sistema apresentará falhas que podem representar riscos para organização e principalmente para as pessoas.&lt;/p&gt;

&lt;p&gt;Comparando as exigências de qualidade sobre sistemas de informação com as práticas de desenvolvimento de software devemos nos questionar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Como desenvolvedores implementam regras de negócio nos sistemas de informação?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Quais práticas podem ser adotadas para codificar regras de forma a garantir a sua corretude?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Quais as estratégias a equipe de desenvolvimento adota para gerenciar o ciclo de vida das regras no sistema?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essas questões serão o guia deste post, que tem por objetivo apresentar conceitos e práticas de design desoftware que podem gerar insgihts valiosos para auxiliar desenvolvedores na modelagem, construção e manutenção de regras de negócio em sistemas de informação.&lt;/p&gt;
&lt;h2&gt;
  
  
  BACKGROUND
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Regras de negócio em Domain-Driven Design
&lt;/h3&gt;

&lt;p&gt;No intuito de aproximar a linguagem de negócio ao design de software, &lt;a href="https://en.wikipedia.org/wiki/Domain-driven_design" rel="noopener noreferrer"&gt;Eric Evans&lt;/a&gt;, em &lt;em&gt;Domain-Driven Design&lt;/em&gt;, propõe a criação de modelos de domínio ricos que representam um "conhecimento destilado" do negócio. Nesse sentido, Evans estabelece os modelos como "a espinha dorsal de uma linguagem utilizada por todos os membros da equipe".&lt;/p&gt;

&lt;p&gt;No entanto, a compreensão do que venha ser um modelo rico é muito abstrata e pode ser repleta de equívocos. Um deles é pensar que um modelo rico se resume a uma espécie de contraste à modelos anêmicos (classes desprovidas de comportamento). Uma das consequências dessa visão restrita, é a construção de entidades excessivamente ricas em comportamentos. Segundo os autores do livro &lt;em&gt;Patterns, Principles, and Practices of Domain-Driven Design&lt;/em&gt;:&lt;/p&gt;




&lt;center&gt;
&lt;strong&gt;✍🏼 CITAÇÃO&lt;/strong&gt;
&lt;br&gt;
&lt;small&gt;
Pessoas novas no DDD tendem a modelar muitos comportamentos. Eles inocentemente acreditam na falácia de que o DDD trata 
de modelar o mundo real. Posteriormente, eles tentam modelar muitos comportamentos do mundo real de uma entidade.
&lt;br&gt;
&lt;strong&gt;Scott Millett e Nick Tune&lt;/strong&gt;
&lt;/small&gt;
&lt;/center&gt;




&lt;p&gt;Evans ainda afirma que "as regras de um negócio geralmente não se enquadram na responsabilidade de uma Entidade ou Objeto de valor", uma vez que elas "podem sobrecarregar o significado básico do objeto do domínio". No entanto, ele reitera que 'retirar as regras da camada de domínio é ainda pior'". Para resolver esse impasse, Evans, toma "emprestado o conceito de predicados e cria objetos especializados que avaliam e fornecem como resposta um resultado booleano".&lt;/p&gt;




&lt;center&gt;
&lt;strong&gt;💡SAIBA MAIS&lt;/strong&gt;
&lt;br&gt;
&lt;small&gt;
Os conceitos de predicado e resultados booleanos remontam um movimento filosófico-matemático do início do século XX chamado de Virada Linguística. Nesse período, os filósofos adotaram a linguagem como foco central de suas investigações. Pensadores como Frege, Russel e Wittgentein, fazendo uso da lógica e da matemática, procuraram uma abordagem formal para explicar e abstrair os fenômenos linguísticos. Esses estudos têm grande influência sobre como hoje concebemos linguagens de programação de alto nível.
&lt;/small&gt;
&lt;/center&gt;




&lt;p&gt;Esses objetos são denominados de &lt;strong&gt;Especificações&lt;/strong&gt; e representam predicados que determinam se o objeto satisfaz ou não alguns critérios. O &lt;strong&gt;Código 1&lt;/strong&gt; ilustra uma especificação da lógica se o cliente é maior de idade. Ao extrair essa lógica para uma classe própria, amplia-se a expressividade, uma vez que o escopo da classe aponta para um único conceito; amplia-se também a testabilidade, já que essa estrutura possui poucas dependências para ser validada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsSatisfiedBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LegalAgeSpecification&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsSatisfiedBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
       &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CalculateAge&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 1.&lt;/b&gt; modelo de especificação em C#&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;A técnica de Especificação é um conceito poderoso em DDD. Contudo, é de certa forma frustrante ver como ela é ocultada no high level conceitual do design. Na visão de blocos de construção do DDD (ver Figura 1) ela não é destacada como os demais conceitos de modelo de domínio. Em seu livro, Evans optou por associar a técnica ao conceito de Objetos de Valor. Demais autores como Vaughn Vernon, Scott Millet e Nick Tune o seguiram nessa mesma linha.&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%2Fr524nnqikgdekhkpttdo.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%2Fr524nnqikgdekhkpttdo.png" alt="DDD"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;b&gt;Figura 1.&lt;/b&gt; blocos de construção do DDD&lt;/small&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Regras de negócio via Design By Contract
&lt;/h3&gt;

&lt;p&gt;As Especificações não são um conceito exclusivos de Evans/Fowler. Duas décadas antes da publicação do DDD, &lt;a href="https://en.wikipedia.org/wiki/Bertrand_Meyer" rel="noopener noreferrer"&gt;Bertrand Meyer&lt;/a&gt;, um mestre em engenharia pela &lt;em&gt;École Polytechnique&lt;/em&gt; em Paris, descreveu no capítulo &lt;strong&gt;Design By Contract: Building Reliable Software&lt;/strong&gt; em seu livro &lt;strong&gt;Object-Oriented: Software Construction&lt;/strong&gt;, como ampliar a confiabilidade (Reliability) de software utilizando uma abordagem chamada &lt;em&gt;Design by Contract&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Em resumo, &lt;em&gt;Design by Contract&lt;/em&gt; aplica um conjunto de regras de relacionamento entre uma classe e seus clientes (consumidores da classe), como um contrato formal composto por pré-condições e pós-condições, que expressam pra cada parte seus direitos e obrigações. Essa relações se dá por &lt;strong&gt;Especificações&lt;/strong&gt; que visam atender o aspecto de corretude (&lt;em&gt;correctness&lt;/em&gt;) da confiabilidade. Para Meyer, "Uma Especificação se dá por &lt;strong&gt;Asserções&lt;/strong&gt;, que são expressões que envolvem e declaram predicados sobre uma entidade, que satisfaçam alguma etapa de execução do software". As asserções podem ser representadas pela seguinte &lt;strong&gt;Fórmula de corretude&lt;/strong&gt;:&lt;/p&gt;



&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;{P} A {Q} 
\text{\textbraceleft P\textbraceright}
\text{ A }
\text{\textbraceleft Q\textbraceright} \
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;{P}&lt;/span&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt; A &lt;/span&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;{Q}&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;






&lt;p&gt;Essa formula expressa que qualquer execução de &lt;strong&gt;A&lt;/strong&gt;, iniciada em um estado mantido por &lt;strong&gt;P&lt;/strong&gt;, será concluída em um&lt;br&gt;
estado mantido por &lt;strong&gt;Q&lt;/strong&gt;. Vejamos o seguinte exemplo,&lt;/p&gt;




&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;{x &amp;gt;= 9} x := x + 5 {x &amp;gt;=13}
\text{\textbraceleft x &amp;gt;= 9\textbraceright}
\text{ x := x + 5 }
\text{\textbraceleft x &amp;gt;=13\textbraceright}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;{x &amp;gt;= 9}&lt;/span&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt; x := x + 5 &lt;/span&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;{x &amp;gt;=13}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;





&lt;p&gt;Nesse exemplo, se &lt;strong&gt;P&lt;/strong&gt; é um número qualquer (x) maior ou igual a 9; e &lt;strong&gt;A&lt;/strong&gt; é função cujo resultado é uma soma desse número mais o número 5; então &lt;strong&gt;Q&lt;/strong&gt; será um número igual ou superior ao número 13. Nessa perspectiva, &lt;strong&gt;"P"&lt;/strong&gt; representa as &lt;strong&gt;pré-condições&lt;/strong&gt; que expressam as condições sobre as quais uma rotina deve funcionar apropriadamente; enquanto &lt;strong&gt;"Q"&lt;/strong&gt; representa as &lt;strong&gt;pós-condições&lt;/strong&gt;, as quais expressam o estado resultante da rotina executada.&lt;/p&gt;

&lt;p&gt;Ainda sobre pré-condições, Meyer afirma que elas são uma &lt;strong&gt;obrigação&lt;/strong&gt; para o cliente e um benefício para o fornecedor. Já as pós-condições, são compreendidas como benefício para o cliente e uma obrigação para o fornecedor.&lt;/p&gt;

&lt;h2&gt;
  
  
  AVALIAÇÃO
&lt;/h2&gt;

&lt;p&gt;Esta seção discute a implementação de regras de negócio em sistemas de informação, destacando desafios associados ao paradigma imperativo e a importância de práticas como o uso de padrões de projeto e asserções para garantir a corretude e facilidade de manutenção.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como desenvolvedores implementam regras de negócio nos sistemas de informação?
&lt;/h3&gt;

&lt;p&gt;A resposta para essa questão está intimamente ligada as linguagens, técnicas e recursos adotados pelos programadores. Numa perspectiva geral, entendo que boa parte das principais linguagens na indústria como C, Java, Python, C# tem um forte traço no paradígma Inperativo.&lt;/p&gt;




&lt;center&gt;
&lt;strong&gt;💡SAIBA MAIS&lt;/strong&gt;
&lt;br&gt;
&lt;small&gt;
As linguagens imperativas são construídas em torno do conceito de mutação de estado e controle de fluxo. 
Isso significa que os programas escritos em linguagens imperativas geralmente modificam seus estados através 
de atribuições a variáveis e usam estruturas de controle como loops (for, while) e condicionais (if-else) para 
controlar a ordem de execução das instruções.
&lt;/small&gt;
&lt;/center&gt;




&lt;p&gt;Apesar de uma parte dessas linguagens oferecerem suporte a outros paradígmas, o traço imperativo ainda tem muita influência sobre como os desenvolvedores escrevem seus programas. O &lt;strong&gt;Código 2&lt;/strong&gt;, ilustrar um exemplo desse tipo de programação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Vineyard is a premium wine retailer that caters to both online &lt;/span&gt;
&lt;span class="c1"&gt;// shoppers and visitors to its physical stores, offering an exquisite &lt;/span&gt;
&lt;span class="c1"&gt;// selection of wines from around the globe. &lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Vineyard.Orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRegistrationUseCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"AVAILABLE"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;InTransit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"IN_TRANSIT"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="nf"&gt;RegisterOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderRegistation&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ThrowIfNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CustomerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isOfLegalAge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Birthday&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProductRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBySku&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sku&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isValidStatus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="n"&gt;InTransit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isNotExpired&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DueDate&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddYears&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// after 1 year, loyal customers get 10%&lt;/span&gt;
                &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;10m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddYears&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// after 5 years, 12%&lt;/span&gt;
                    &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;12m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// first time purchase discount of 15%&lt;/span&gt;
            &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;15m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTheBirthday&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;0.05m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;IsElegible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;isOfLegalAge&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isValidStatus&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isNotExpired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;//TODO : Register in Database&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 2.&lt;/b&gt; código imperativo&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;O código C# apresentado anteriormente ilustra uma aplicação da &lt;em&gt;Vineyard&lt;/em&gt;, uma loja fictícia especializada na venda de vinhos importados. Nesse código há uma classe chamada &lt;code&gt;OrderRegistrationUseCase&lt;/code&gt; que implementa o método &lt;code&gt;RegisterOrder(OrderRegistation command)&lt;/code&gt;, cuja responsabilidade é registrar a entidade &lt;code&gt;Order&lt;/code&gt;. Para isso o serviço faz uso das seguintes regras:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O &lt;code&gt;Pedido&lt;/code&gt; deve conter um &lt;code&gt;Cliente&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Cliente&lt;/code&gt; deve ter idade igual ou superior a 18 anos&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Pedido&lt;/code&gt; deve conter um &lt;code&gt;Produto&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Produto&lt;/code&gt; deve estar no status &lt;code&gt;AVAILABLE&lt;/code&gt; ou &lt;code&gt;IN_TRANSIT&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Produto&lt;/code&gt; não pode estar vencido&lt;/li&gt;
&lt;li&gt;Quando a data da primeira compra do &lt;code&gt;Cliente&lt;/code&gt; for superior a 1 ano, ele receberá um desconto de 10%.&lt;/li&gt;
&lt;li&gt;Quando a data da primeira compra do &lt;code&gt;Cliente&lt;/code&gt; for superior a 5 ano, ele receberá um desconto de 12%.&lt;/li&gt;
&lt;li&gt;Quando for a primeira compra do &lt;code&gt;Cliente&lt;/code&gt;, ele receberá um desconto de 15%.&lt;/li&gt;
&lt;li&gt;Se for o aniversário do &lt;code&gt;Cliente&lt;/code&gt;, ele receberá mais um acréscimo de 5% de desconto.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apesar de ilustrativo, esse código baseia-se em uma implementação real, na qual as regras de negócio estão escritas de forma imperativa no código. Isso não é algo raro, e pode ser identificado em diversos sistemas, de diferentes domínios. Nesse tipo de implementação as origens e motivações das regras de negócio que foram parar no código-fonte estão ocultas, possivelmente perdida em algum artefato estático ou na mente de algum especialista.&lt;/p&gt;




&lt;center&gt;
&lt;strong&gt;🤔 OPINIÃO&lt;/strong&gt;
&lt;br&gt;
&lt;small&gt;
Particularmente, enxergo o código-fonte para além de um conjunto de instruções de máquina. Ao meu ver ele deveria ser compreendido como um artefato de comunicação entre desenvolvedores na etapa de codificação. Gosto de pensar, que dentre todos os artefatos do ciclo de vida de desenvolvimento de software, o código-fonte é um dos mais dinâmicos. Talvez essas ideias sejam influenciadas por meu apreço por um movimento no qual muitos dos artefatos da engenharia de software são "as a code". 
&lt;/small&gt;
&lt;/center&gt;




&lt;h3&gt;
  
  
  Quais práticas podem ser adotadas para codificar regras de forma a garantir a sua corretude?
&lt;/h3&gt;

&lt;p&gt;Nesta seção ilustraremos o uso de algumas práticas para codificar regras de negócio no software. Para isso, faremos uso de algumas regras defenidas Meyer para o uso de Epecificações. Elas formam um conjunto de orientam a criação de Asserções e partem do princípio que "em nenhuma circustância o corpo de uma rotina deve testar suas precondições". São elas:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asserções não são mecanismos para validar inputs;&lt;/li&gt;
&lt;li&gt;Asserções não são estruturas de controle;&lt;/li&gt;
&lt;li&gt;Use Asserções para escrever softwares corretos;&lt;/li&gt;
&lt;li&gt;Use Asserções para documentação;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Asserções não são mecanismos para validar inputs
&lt;/h4&gt;

&lt;p&gt;As asserções devem validar apenas o escopo da regra de negócio à qual se propõe. Nesse sentido, crie módulos especializados para tratar validações de input. Uma forma de fazer isso pode ser utilizando padrões como decorator, para isolar o código que irá validar os objetos de input da rotina. o &lt;strong&gt;Código 3&lt;/strong&gt; ilustra um exemplo de implementação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRegistrationValidation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrderRegistrationUseCase&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IOrderRegistrationUseCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="nf"&gt;RegisterOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderRegistation&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ThrowIfNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CustomerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ThrowIfNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProductRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBySku&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sku&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ThrowIfNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RegisterOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 3.&lt;/b&gt; exemplo de uso do padrão decorator para validação de inputs&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Ao remover as validações de input da classe &lt;code&gt;OrderRegistrationUseCase&lt;/code&gt;, diminui-se sua complexidade, fazendo com que o escopo de negócio seja isolado. O &lt;strong&gt;Código 4&lt;/strong&gt; ilustra o método &lt;code&gt;OrderRegistrationUseCase&lt;/code&gt; sem as validações de input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRegistrationUseCase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IOrderRegistrationUseCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"AVAILABLE"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;InTransit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"IN_TRANSIT"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="nf"&gt;RegisterOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderRegistation&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isOfLegalAge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Birthday&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isValidStatus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="n"&gt;InTransit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isNotExpired&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DueDate&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddYears&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// after 1 year, loyal customers get 10%&lt;/span&gt;
                &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;10m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddYears&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// after 5 years, 12%&lt;/span&gt;
                    &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;12m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// first time purchase discount of 15%&lt;/span&gt;
            &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;15m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTheBirthday&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;05m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;IsElegible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;isOfLegalAge&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isValidStatus&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isNotExpired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;//TODO : Register in Database&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 4.&lt;/b&gt; resultado do código sem as validações de input&lt;/small&gt;&lt;/p&gt;



&lt;h4&gt;
  
  
  Asserções não são estruturas de controle
&lt;/h4&gt;

&lt;p&gt;Seguindo o princípio de que "o corpo de uma rotina não deve testar suas precondições", precisamos tornar nosso o código mais declarativo. Para isso removeremos os fluxos de validação para que eles não formem estruturas de controle.Uma das formas possíveis para executar isso é extrair as regras de negócio do método &lt;code&gt;RegisterOrder&lt;/code&gt; para métodos novos na classe &lt;code&gt;OrderRegistrationUseCase&lt;/code&gt;. O &lt;strong&gt;Código 5&lt;/strong&gt; ilustra o resultado dessa extração.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRegistrationUseCase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IOrderRegistrationUseCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"AVAILABLE"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;InTransit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"IN_TRANSIT"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="nf"&gt;RegisterOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderRegistation&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;IsElegible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;IsOrderEligible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;CalculateDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;//TODO : Register in Database&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsOrderEligible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;CalculateDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 5.&lt;/b&gt;resultado do código sem as regras no corpo do método&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Após essas pequenas mudanças, o &lt;strong&gt;Código 5&lt;/strong&gt; encontra-se bem diferente do &lt;strong&gt;Código 2&lt;/strong&gt;. O método &lt;code&gt;RegisterOrder&lt;/code&gt; da classe &lt;code&gt;OrderRegistrationUseCase&lt;/code&gt; agora apresenta um escopo mais declarativo. Contudo, como garantir a corretude de nossas regras?&lt;/p&gt;



&lt;h4&gt;
  
  
  Use Asserções para escrever softwares corretos
&lt;/h4&gt;

&lt;p&gt;Com as extrações relaizadas na classe &lt;code&gt;OrderRegistrationUseCase&lt;/code&gt;, foi possível remover as estruturas de controle que estavam no corpo do método, promovendo uma melhor legibilidade ao código. O próximo passo é isolar as Asserções da classe &lt;code&gt;OrderRegistrationUseCase&lt;/code&gt;, tornando-as mais atômicas, reutilizáveis e passíveis de teste.Para isso, será adotado o &lt;a href="https://www.pluralsight.com/courses/c-sharp-design-patterns-rules-pattern" rel="noopener noreferrer"&gt;Business Rule Pattern&lt;/a&gt;, proposto por &lt;a href="https://ardalis.com/blog" rel="noopener noreferrer"&gt;Steve Smith&lt;/a&gt;. Estes são algums pontos importantes a serem observadas sobre o &lt;em&gt;pattern&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cada regra deve seguir o &lt;strong&gt;Single Responsibility Principle&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Para garantir que a regra siga o Princípio da Responsabilidade Única, tenha em mente o Princípio &lt;strong&gt;KISS&lt;/strong&gt;!&lt;/li&gt;
&lt;li&gt;As regras podem ser ordenadas, filtradas ou agregadas conforme necessário.&lt;/li&gt;
&lt;li&gt;O motor de regras determina como processar as regras.&lt;/li&gt;
&lt;li&gt;A lógica para determinar as prioridades das regras reside no motor de regras.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O primeiro passo para implementar esse padrão, será a remoção do métodos de validação criados no &lt;strong&gt;Código 5&lt;/strong&gt; para uma estrutura própria. O &lt;strong&gt;Código 6&lt;/strong&gt; demonstra o resultado da transformação desses métods em Asserções da entidade &lt;code&gt;Customer&lt;/code&gt; em uma classe chamada &lt;code&gt;CustomerRules&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomerRules&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsOfLegalAge&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CalculateAge&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsFisrtPurchase&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;  

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsLoyalCustomers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;years&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddYears&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;years&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;     
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 6.&lt;/b&gt;criação das Asserções da entidade Customer&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Agora a classe &lt;code&gt;CustomerRules&lt;/code&gt; possui uma maior autonomia em relação ao &lt;code&gt;OrderRegistrationUseCase&lt;/code&gt;. Cada uma de suas sub-classes implementa a interface ISpecification e possui comportamento livre de efeitos colaterais e são passíveis de testáveis automatizados.&lt;/p&gt;

&lt;p&gt;Em seguida, será necessário criar a classe que fará a composição das Asserções para lidar como a regra de negócio. No Padrão &lt;em&gt;Business Rule Pattern&lt;/em&gt; esse tipo de classe é denominada &lt;strong&gt;Motor de Regras&lt;/strong&gt; (&lt;em&gt;Rules Engine&lt;/em&gt;). O &lt;strong&gt;Código 7&lt;/strong&gt; demonstra a implementação do Motor de Regas &lt;code&gt;IsOrderEligible&lt;/code&gt;, que determina se um pedido é elegível ou não.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsOrderEligible&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LegalAgeSpecification&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CustomerRules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsOfLegalAge&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ProductSpecs&lt;/span&gt;  &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ProductRules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsAvaliableOrInTransit&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ProductRules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNotExpired&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;LegalAgeSpecification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;spec&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ProductSpecs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 7.&lt;/b&gt; criação do Motor de Regas&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Com a extração de todas as regras que estavam acopladas ao caso de uso, o &lt;strong&gt;Código 2&lt;/strong&gt; foi refatorado para uma versão mais declarativa focada em especificações em vez de instruções. O &lt;strong&gt;Código 8&lt;/strong&gt; apresenta a versão final da classe &lt;code&gt;OrderRegistrationUseCase&lt;/code&gt; após a refatoração.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRegistrationUseCase&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IOrderRegistrationUseCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="nf"&gt;RegisterOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderRegistationCommand&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;IsElegible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IsOrderEligible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CalculateDiscount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;//TODO : Register in Database&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 8.&lt;/b&gt; resultado final da classe OrderRegistrationUseCase&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Quais as estratégias a equipe de desenvolvimento adota para gerenciar o ciclo de vida das regras no sistema?
&lt;/h3&gt;

&lt;p&gt;Reservamos esta seção para apresentar a última das regra listadas na seção anterior. Com ela abordaremos como associar os  benefícios das práticas adotadas anterirormente à prática de documentação afim de se obter uma melhor para a manutenção, compreensão e colaboração. &lt;/p&gt;



&lt;h4&gt;
  
  
  Use Asserções para documentação
&lt;/h4&gt;

&lt;p&gt;Aproveitando o isolamento das Assertions que foram implementadas na seção anteriror, é possível usar todos os recuros  do compilador da linguagem C# como comentários e atributos para documentar as regras de negócio. Essa é uma forma de manter uma rastreabilidade  e gestão das regras de negócio que foram incluídas no projeto ao longo do tempo mais claras para o time de desenvolvimento.  Os &lt;strong&gt;Código 9&lt;/strong&gt; e &lt;strong&gt;Código 10&lt;/strong&gt; apresentam um exemplo de documentação das regras.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomerRules&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// No Brasil, o consumo de bebidas alcoólicas por menores de 18 anos&lt;/span&gt;
    &lt;span class="c1"&gt;/// é proibido. A Lei federal 13.106/16 alterou o Estatuto da Criança&lt;/span&gt;
    &lt;span class="c1"&gt;/// e do Adolescente, tornando crime vender, fornecer, servir, ministrar&lt;/span&gt;
    &lt;span class="c1"&gt;/// ou entregar bebida alcoólica a criança ou adolescente.&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;see href="https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2015/lei/l13106.htm"/&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsOfLegalAge&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CalculateAge&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// Regra de primeira compra definida pelo Gestor do Departamento de Marketing&lt;/span&gt;
    &lt;span class="c1"&gt;/// e acolhida pelo gerente de vendas durante a Black Friday&lt;/span&gt;
    &lt;span class="c1"&gt;/// de 2022.&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;see href="https://sistema-interno/features/98098999"/&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Obsolete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Regra válida até Julho de 2023"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsFisrtPurchase&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;  

    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// Implantação do programa de fidelidade após resultados da&lt;/span&gt;
    &lt;span class="c1"&gt;/// Black Friday de 2022 &lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;see cref="IsFisrtPurchase"/&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;see href="https://sistema-interno/features/99090000"/&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsLoyalCustomers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;years&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfFirstPurchase&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddYears&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;years&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;     
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 9.&lt;/b&gt; uso de comentários e attributes nas Asserções&lt;/small&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// Regra de desconto durante o registro do Pedido&lt;/span&gt;
&lt;span class="c1"&gt;/// Os descontos são concedidos nos seguintes casos:&lt;/span&gt;
&lt;span class="c1"&gt;/// 1 - Primeira compra = 15%&lt;/span&gt;
&lt;span class="c1"&gt;/// 2 - Cliente fidelidade com mais de 1 ano = 10%&lt;/span&gt;
&lt;span class="c1"&gt;/// 3 - Cliente fidelidade com mais de 1 ano = 12%&lt;/span&gt;
&lt;span class="c1"&gt;/// 4 - Cliente aniversariantes acréscimo de 5% ao desconto obtido&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;see cref="CustomerRules.IsFisrtPurchase"/&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;see cref="CustomerRules.IsLoyalCustomers"/&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;see href="https://sistema-interno/features/99090000"/&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculateDiscount&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;(&lt;/span&gt;&lt;span class="n"&gt;ISpecification&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Discount&lt;/span&gt;&lt;span class="p"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;CustomerSpecs&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CustomerRules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsFisrtPurchase&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;15m&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CustomerRules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsLoyalCustomers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;10m&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CustomerRules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsLoyalCustomers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="m"&gt;0.12m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;spec&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;CustomerSpecs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Discount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTheBirthday&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;05m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;    
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;&lt;b&gt;Código 10.&lt;/b&gt; documentação de motor de regas&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Há desenvolvedores que não são favoráveis a esse tipo de documentação em código. Contudo, olhando para um contexto no qual uma equipe constantemente precisa alterar regras na aplicação e que essas regras não possuem um registro adequado ou prático, manter essa informação no código proporcionará um pouco de rastreabilidade para esse tipo de mudança, que dificilmente estará explicita em um sistema de versionamento de código.&lt;/p&gt;



&lt;h4&gt;
  
  
  Mantenha tudo Organizado
&lt;/h4&gt;

&lt;p&gt;Um último aspecto que precisa ser discutido é a organização da estrutura de código para comportar as regras de negócio.A solução aqui apresentada, foi organizada da seguinte forma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A classes de Asserção foram colocadas junto aos Modelos de Domínio; &lt;/li&gt;
&lt;li&gt;Já os motores de regas foram colocados no escopo do caso de uso dentro de uma pasta chamada &lt;code&gt;BusinessRules&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Cada motor foi separado por categoria.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em nosso exemplo, implementamos dois tipos de padrão de motor: de &lt;strong&gt;Eligibility Pattern&lt;/strong&gt; e &lt;strong&gt;Eligibility Pattern&lt;/strong&gt;. Tomando como referência o conceito de &lt;em&gt;Business Rule Management System (BRMS)&lt;/em&gt; apresentado no post de &lt;a href="https://blogs.perficient.com/2017/09/17/10-business-rule-patterns-in-the-digital-transformation-and-cognitive-era/" rel="noopener noreferrer"&gt;Amit Tlekar&lt;/a&gt;. Nele é apresentado outros padrões de motores de regas como &lt;em&gt;Validation Pattern, Authority and Approval Pattern, Legacy Rules Extraction,Scoring &amp;amp; Selection Pattern, Unstructured Big data pattern, Events pattern&lt;/em&gt; etc. A &lt;strong&gt;Figura 2&lt;/strong&gt; ilustra a organização da final da solução.&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%2Finde33ilp2lm35n4z61t.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%2Finde33ilp2lm35n4z61t.png" alt="Projeto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;b&gt;Figura 2.&lt;/b&gt; estrutura de solução&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O texto discute a complexidade de definir e implementar regras de negócio em sistemas de informação dentro do campo da engenharia de software. Enfatiza a importância da colaboração entre desenvolvedores e especialistas do negócio para criar estruturas de software que atendam às exigências de qualidade e respondam adequadamente às demandas do negócio. Métodos como Business Process Management (BPM), Domain-Driven Design (DDD), e Business Capability Analysis são destacados como essenciais para mapear e expressar regras de negócio de forma efetiva.&lt;/p&gt;

&lt;p&gt;O texto aprofunda-se em conceitos de Domain-Driven Design (DDD) e Design by Contract, propostos respectivamente por Eric Evans e Bertrand Meyer, para ilustrar abordagens na modelagem de domínios ricos e na implementação de regras de negócio com confiabilidade. As especificações são apresentadas como uma técnica para definir critérios claros e verificáveis, enquanto as asserções e contratos formais entre classes e seus consumidores são discutidos como métodos para garantir a corretude e confiabilidade do software.&lt;/p&gt;

&lt;p&gt;Por fim, o texto aborda práticas recomendadas para codificar, documentar e manter regras de negócio nos sistemas de informação, destacando a importância de isolamento das validações, uso de asserções para corretude, e documentação adequada para facilitar a manutenção e compreensão. Estas práticas são apontadas como fundamentais para o desenvolvimento de sistemas robustos, flexíveis e alinhados com os objetivos do negócio,ressaltando a necessidade contínua de adaptação e evolução das regras de negócio diante das mudanças do mercado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;Este texto serve como uma revisão focada nos conceitos de "Design by Contract", com especial atenção à sua implementação na linguagem C#. Embora procuremos abordar os principais pontos e oferecer insights sobre como esses conceitos se aplicam ao desenvolvimento de software, é importante reconhecer que a discussão aqui apresentada não esgota a profundidade e a amplitude do "Design by Contract".&lt;/p&gt;




&lt;p&gt;Caros leitores,&lt;/p&gt;

&lt;p&gt;Espero que tenham encontrado insights valiosos na discussão sobre o design e organização de código.&lt;/p&gt;

&lt;p&gt;Se você já experimentou essas estratégias em seus projetos, como foi? Quais vantagens e obstáculos você encontrou? Se ainda não tentou, consideraria implementá-la após essa leitura?&lt;/p&gt;

&lt;p&gt;Seu feedback é crucial para enriquecer essa discussão.&lt;/p&gt;

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

&lt;p&gt;Você pode acessar o código-fonte desse exemplo clicando &lt;a href="https://github.com/yanjustino/Vineyard" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://softwarehut.com/blog/tech/design-patterns-rules-engine" rel="noopener noreferrer"&gt;https://softwarehut.com/blog/tech/design-patterns-rules-engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.michael-whelan.net/rules-design-pattern/" rel="noopener noreferrer"&gt;https://www.michael-whelan.net/rules-design-pattern/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://app.pluralsight.com/ilx/video-courses/48850dfa-8620-48b9-b107-9db26d07061f/7c537ceb-2b27-4a3e-8007-ae787459c4ef/a0167771-dc9a-46e2-b2d5-73c66fde13b3" rel="noopener noreferrer"&gt;https://app.pluralsight.com/ilx/video-courses/48850dfa-8620-48b9-b107-9db26d07061f/7c537ceb-2b27-4a3e-8007-ae787459c4ef/a0167771-dc9a-46e2-b2d5-73c66fde13b3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deviq.com/design-patterns/rules-engine-pattern" rel="noopener noreferrer"&gt;https://deviq.com/design-patterns/rules-engine-pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.perficient.com/2017/09/17/10-business-rule-patterns-in-the-digital-transformation-and-cognitive-era/" rel="noopener noreferrer"&gt;https://blogs.perficient.com/2017/09/17/10-business-rule-patterns-in-the-digital-transformation-and-cognitive-era/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://martinfowler.com/bliki/BusinessReadableDSL.html" rel="noopener noreferrer"&gt;https://martinfowler.com/bliki/BusinessReadableDSL.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Business Rules</title>
      <dc:creator>Yan Justino</dc:creator>
      <pubDate>Sun, 03 Mar 2024 22:25:48 +0000</pubDate>
      <link>https://dev.to/yanjustino/business-rules-53o8</link>
      <guid>https://dev.to/yanjustino/business-rules-53o8</guid>
      <description>&lt;h2&gt;
  
  
  CONTEXTO
&lt;/h2&gt;

&lt;p&gt;Alcançar uma clara definição de fronteiras de um sistema é um dos grandes desafios no Design Arquitetural de um software. Nessa etapa, são concebidos artefatos como módulos, componetes e seus conectores, bem como, as estruturas de alocação que satisfazem um conjunto de requisitos que, mediante a determinadas expectativas de qualidade, respondam às demandas do negócio.   &lt;/p&gt;

&lt;p&gt;Nesse contexto, o papel do desenvolvimento é "preencher" as lacunas dessas estruturas de software com comportamentos (ricos) do domínio. Para isso, equipes de desenvolvimento têm adotado métodos como &lt;em&gt;Business Process Management&lt;/em&gt; (BPM), &lt;em&gt;Domain-Driven Design&lt;/em&gt; (DDD), &lt;em&gt;Business Capability Analysis&lt;/em&gt; etc, para identificar possíveis fronteiras e estruturas que representem o domínio do negócio.&lt;/p&gt;

&lt;p&gt;Contudo, a adoção desses métodos, por si só, não garante que desenvolvedores implementem esses comportamentos de negócio de forma adequada ao ponto que eles sejam livres de efeitos colaterais e fáceis em sua manutenção. Afim de ilustrar as práticas do &lt;em&gt;Design by Contract&lt;/em&gt;, o código a seguir é uma representação de um software que será adaptado ao longo desse post para atender os princípios desse conceito.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Vineyard is a premium wine retailer that caters to both online shoppers and visitors to its physical stores,&lt;/span&gt;
&lt;span class="c1"&gt;// offering an exquisite selection of wines from around the globe. &lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Vineyard.Orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"AVAILABLE"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;InTransit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"IN_TRANSIT"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Ecommerce&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ECOMMERCE"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;BrickAndMortaStore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"BRICK_AND_MORTA_STORE"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="nf"&gt;RegisterOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OrderRegistation&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CustomerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isOfLegalAge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Birthday&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProductRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBySku&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sku&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isValidStatus&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="n"&gt;InTransit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isNotExpired&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
                           &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DueDate&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isValidWinery&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Plataform&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;BrickAndMortaStore&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
                                  &lt;span class="n"&gt;CategoryRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AccreditedWineries&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CategoryId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

            &lt;span class="n"&gt;Ecommerce&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
                         &lt;span class="n"&gt;CategoryRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AccreditedWineries&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CategoryId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
                         &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;CategoryRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WineriesBlockedFromEcommerce&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CategoryId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;IsProcessableOrder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;isOfLegalAge&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isValidStatus&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isNotExpired&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isValidWinery&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;//TODO : Register in Database&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;Exemplo. código C#&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;O código C# apresentado anteriormente ilustra uma aplicação da &lt;em&gt;Vineyard&lt;/em&gt;, uma loja fictícia especializada na venda de vinhos importados. Nesse código há uma classe chamada &lt;code&gt;OrderService&lt;/code&gt; que impelementa o método &lt;code&gt;RegisterOrder(OrderRegistation command)&lt;/code&gt;, cuja responsabilidade é registrar a entidade &lt;code&gt;Order&lt;/code&gt;. Para isso o serviço faz uso das seguintes regras:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O &lt;code&gt;Pedido&lt;/code&gt; deve conter um &lt;code&gt;Cliente&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Cliente&lt;/code&gt; deve ter idade igual ou superior a 18 anos&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Pedido&lt;/code&gt; deve conter um &lt;code&gt;Produto&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Produto&lt;/code&gt; deve estar no status &lt;code&gt;AVAILABLE&lt;/code&gt; ou &lt;code&gt;IN_TRANSIT&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Produto&lt;/code&gt; não pode estar vencido&lt;/li&gt;
&lt;li&gt;Quando a venda for realizada pela loja física, o &lt;code&gt;Produto&lt;/code&gt; deve pertencer a uma &lt;code&gt;Vinicula&lt;/code&gt; credenciada.&lt;/li&gt;
&lt;li&gt;Quando a venda for realizada pelo e-commerce, o &lt;code&gt;Produto&lt;/code&gt;, além de pertencer a uma &lt;code&gt;Vinicula&lt;/code&gt; credenciada, não pode ser de uma &lt;code&gt;Vinicula&lt;/code&gt; bloqueada para esse canal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apesar de ilustrativo, esse código basea-se em um caso bem próximo de uma implementação real, no qual as regras de negócio estão escritas de forma imperativa em classes de serviço. Isso não é algo raro, e pode ser identificado em diversos sistemas de domínios diferentes.  &lt;/p&gt;

&lt;p&gt;Numa perspectiva do DDD, os autores do livro &lt;a href="https://books.google.com.br/books/about/Patterns_Principles_and_Practices_of_Dom.html?id=0-fGBwAAQBAJ&amp;amp;source=kp_book_description&amp;amp;redir_esc=y"&gt;&lt;em&gt;Patterns, Principles, and Practices of Domain-Driven Design&lt;/em&gt;&lt;/a&gt;, Scott Millett e Nick Tune, afirmam que:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;people new to DDD tend to model too much behavior. They innocently by into the fallacy that DDD is about modeling the real world. Subsequently, they try to model many real-world behaviors of an entity...   &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O código     &lt;/p&gt;

&lt;h2&gt;
  
  
  DESIGN BY CONTRACT
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Corretude
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://dev.tourl"&gt;Confiabilidade&lt;/a&gt; de um sistema está na sua capacidade de executar, de forma consistente, suas funções conforme esperado. A &lt;strong&gt;corretude&lt;/strong&gt; é uma de suas características da&lt;/p&gt;

&lt;h3&gt;
  
  
  Especificação
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Assertation
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Pré-condições e Pós-condições
&lt;/h3&gt;

&lt;p&gt;No capítulo "DESIGN BY CONTRACT: BUILDING RELIABLE SOFTWARE" do seu livro "Object-Oriented: software construction", Bertrand Meyer descorre sobre como expressar especificações, asserções &lt;/p&gt;

&lt;h2&gt;
  
  
  CONTEXTOS FILOSÓFICOS
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Esta é uma leitura opcional no texto. Embora possa oferecer insights interessantes e uma compreensão mais profunda do tema em discussão, reconhecemos que nem todos os leitores têm interesse ou tempo para se aprofundar nesses aspectos. Portanto, sinta-se à vontade para explorar essa seção conforme sua conveniência e interesse pessoal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Passou-se um pouco mais de um século que as reflexões de Frege e Boole sobre inauguraram uma nova perpectiva matemática e filosófiica sobre a lógica &lt;br&gt;


&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;P  ⟹  QP\implies Q&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;P&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;⟹&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;Q&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
. &lt;/p&gt;

&lt;p&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;p&amp;gt;q
p&amp;gt;q
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;q&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;As regras de negócio em seu código escondem um segredo que remonta uma tradição filosófica que atravessou milênios. Como velhas ruínas, as validações escritas em linguagem de programação, envolvidas por métodos e funções, tem em seu coração os princípios da lógica&lt;/p&gt;

&lt;p&gt;Referencias&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://softwarehut.com/blog/tech/design-patterns-rules-engine"&gt;https://softwarehut.com/blog/tech/design-patterns-rules-engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.michael-whelan.net/rules-design-pattern/"&gt;https://www.michael-whelan.net/rules-design-pattern/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://app.pluralsight.com/ilx/video-courses/48850dfa-8620-48b9-b107-9db26d07061f/7c537ceb-2b27-4a3e-8007-ae787459c4ef/a0167771-dc9a-46e2-b2d5-73c66fde13b3"&gt;https://app.pluralsight.com/ilx/video-courses/48850dfa-8620-48b9-b107-9db26d07061f/7c537ceb-2b27-4a3e-8007-ae787459c4ef/a0167771-dc9a-46e2-b2d5-73c66fde13b3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deviq.com/design-patterns/rules-engine-pattern"&gt;https://deviq.com/design-patterns/rules-engine-pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.perficient.com/2017/09/17/10-business-rule-patterns-in-the-digital-transformation-and-cognitive-era/"&gt;https://blogs.perficient.com/2017/09/17/10-business-rule-patterns-in-the-digital-transformation-and-cognitive-era/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://martinfowler.com/bliki/BusinessReadableDSL.html"&gt;https://martinfowler.com/bliki/BusinessReadableDSL.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Além dos Templates: Uma Crítica Construtiva à Arquitetura Limpa e a Adaptação Pragmática no Design de Software</title>
      <dc:creator>Yan Justino</dc:creator>
      <pubDate>Sun, 18 Feb 2024 22:14:18 +0000</pubDate>
      <link>https://dev.to/yanjustino/alem-dos-templates-uma-critica-construtiva-a-arquitetura-limpa-e-a-adaptacao-pragmatica-no-design-de-software-1l2</link>
      <guid>https://dev.to/yanjustino/alem-dos-templates-uma-critica-construtiva-a-arquitetura-limpa-e-a-adaptacao-pragmatica-no-design-de-software-1l2</guid>
      <description>&lt;p&gt;&lt;strong&gt;YAN JUSTINO&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://repositorio.ufrn.br/handle/123456789/26370" rel="noopener noreferrer"&gt;MSc. Software Engineering&lt;/a&gt; · &lt;a href="https://www.cesar.school/doutorado-profissional-em-engenharia-de-software/" rel="noopener noreferrer"&gt;PhD. Student&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;AWS&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;MCSD&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges" rel="noopener noreferrer"&gt;OCA&lt;/a&gt; · &lt;a href="https://orcid.org/0000-0001-7248-716X" rel="noopener noreferrer"&gt;ORCID&lt;/a&gt;  · &lt;a href=""&gt;Tech Lead at ITAÚ Unibanco&lt;/a&gt;&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%2Fimg.shields.io%2Fbadge%2Fpost-design-50A6C5%3Fstyle%3Dfor-the-badge" 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%2Fimg.shields.io%2Fbadge%2Fpost-design-50A6C5%3Fstyle%3Dfor-the-badge" alt="Static Badge"&gt;&lt;/a&gt; &lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;Mas não se preocupe, meu amigo&lt;br&gt;
Com os horrores que eu lhe digo&lt;br&gt;
Isto é somente uma canção&lt;br&gt;
A vida realmente é diferente&lt;br&gt;
Quer dizer, ao vivo é muito pior - &lt;strong&gt;Belchior&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  1. CONTEXTUALIZAÇÃO
&lt;/h2&gt;

&lt;p&gt;As últimas duas décadas foram marcadas por mudanças significativas na forma em que modelamos, construímos, implantamos e mantemos softwares. Testemunhamos na indústria a consolidação do &lt;em&gt;Domain-Driven Design (DDD)&lt;/em&gt;, a ascensão da &lt;em&gt;Cloud Computing&lt;/em&gt; e da &lt;em&gt;Service-Orientation&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Também presenciamos o surgimento de conceitos como &lt;em&gt;Data Lake&lt;/em&gt; e &lt;em&gt;Data Mesh&lt;/em&gt;, que vieram ampliar os recursos e aspectos voltados à análise e tomada de decisão.Todos esses movimentos da engenharia de software possuem uma forte influência de design centrada nos aspectos de domínio de negócio. &lt;/p&gt;

&lt;p&gt;Imerso no contexto dessas transformações, lembro-me de discussões acaloradas nos fóruns de tecnologia sobre quão pobre eram as minhas aplicações modeladas usando conceitos como &lt;a href="https://learn.microsoft.com/en-us/aspnet/web-forms/overview/data-access/introduction/creating-a-business-logic-layer-cs" rel="noopener noreferrer"&gt;MVC, Poco, Presentation, BLL e DAL etc&lt;/a&gt;, em detrimento a poderosa e rica organização que oferecia o DDD. &lt;/p&gt;

&lt;p&gt;Lembro do entusiasmo e da forte influência dos meus gurus e de como em pouco tempo eu também me tornara um (chato) evangelista do Eric Evans, Vaughn Vernon e Scott Millet... &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Amadurecer nos traz o benefício e a oportunidade de rir de nós mesmos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nas contas do tempo, me recordo de alguns pecados contra o DDD que nós, vigilantes e ávidos acólitos, estávamos prontos pra denunciar. Um deles é proibido de ser pronunciado até hoje: "DDD é um padrão arquitetural". Essa é uma lacuna conceitual que ainda persiste: há uma certa predileção por parte dos desenvolvedores aos &lt;a href="https://learn.microsoft.com/pt-br/azure/architecture/microservices/model/tactical-ddd" rel="noopener noreferrer"&gt;padrões táticos&lt;/a&gt; do que os aspecto estratégicos do DDD. &lt;/p&gt;

&lt;p&gt;Nesse sentido, se criou um certo &lt;em&gt;imbróglio&lt;/em&gt;. Desenvolvedores que passaram a adotar DDD tinham uma nítida impressão que estavam fazendo algo diferente: a organização de suas aplicações agora tinham uma estrutura mais semântica, mais expressiva e próxima a linguagem do negócio. No entanto, ter o benefício dessa organização não significava exatamente que a equipe de desenvolvimento tivesse aplicado as abordagens estratégicas do DDD. &lt;/p&gt;

&lt;p&gt;Nesse aspecto, dizer que sua aplicação usava um padrão arquitetural chamado DDD parecia, até certo ponto, incoerente. Esse tipo de confusão muitas vezes era respaldada por iniciativas como o &lt;a href="https://devblogs.microsoft.com/cesardelatorre/great-diagram-about-our-ddd-nlayered-net-4-0-architecture/" rel="noopener noreferrer"&gt;&lt;em&gt;DDD N-Layered .NET 4.0 Architecture Guide&lt;/em&gt;&lt;/a&gt;, um guia que orientava como desenvolvedores poderiam organizar suas aplicações baseando-se em conceitos de DDD. Esse modelo foi amplamente disseminado e até hoje encontramos aplicações estruturadas seguindo essa proposta:&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%2F59id2runj5q4gsfuef45.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%2F59id2runj5q4gsfuef45.png" alt="DDD N-Layered Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;b&gt;Figura.&lt;/b&gt; modelo em camadas aplicando DDD&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Posteriormente esse tipo de iniciativa também foi duramente criticada por "reduzir" os aspectos de domínio a uma mera organização de pastas que mais expressavam linguagem de software e não de negócio. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nothing here talks about what the application does - &lt;strong&gt;Uncle Bob.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nessa linha, o &lt;a href="https://blog.cleancoder.com" rel="noopener noreferrer"&gt;Robert C. Martin (&lt;strong&gt;Uncle Bob&lt;/strong&gt;)&lt;/a&gt; em uma emblemática talk na Ruby Midwest 2011, confrontou a comunidade de desenvolvedores Rails questionando-a o porquê de suas aplicações não expressar uma linguagem de negócio em seu &lt;em&gt;Top Level Architecture&lt;/em&gt;. O vídeo dessa talk pode ser assistido no link a seguir:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://www.youtube.com/watch?si=S8XT9DVLuvFZN-HS&amp;amp;v=WpkDN78P884&amp;amp;feature=youtu.be" rel="noopener noreferrer"&gt;
      youtube.com
    &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Algo me leva a crer que o Uncle Bob, diante de toda sua experiência e percebendo os conflitos e lacunas conceituais de design da época, vislumbrou a oportunidade de pavimentar o caminho para mais uma de suas publicações, daquela que chamo de "cleanware" - livros com o título "X Limpo".&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html" rel="noopener noreferrer"&gt;&lt;em&gt;Clean Architecture&lt;/em&gt;&lt;/a&gt;, é uma obra de 2017 que pertence ao conjunto de publicações que representa a visão idealizada de Robert C. Martin (&lt;strong&gt;Uncle Bob&lt;/strong&gt;) sobre princípios e boas práticas no design de software. &lt;/p&gt;

&lt;p&gt;Segundo o autor, o objetivo da &lt;em&gt;Clean Architecture&lt;/em&gt; é o desenvolvimento de sistemas fáceis de manter, testar, e estender ao longo do tempo, além de promover a separação de responsabilidades em diferentes camadas.&lt;/p&gt;

&lt;p&gt;Em pouco tempo a &lt;em&gt;Clean Architecture&lt;/em&gt; alcançou uma certa popularidade e influência sobre os projetos de software na industria. Ao meu ver, a fama do autor do "Código Limpo" somada as similaridades de design que os desenvolvedores já adotavam utilizando os padrões táticos de DDD, foram decisivos para o engajamento à &lt;em&gt;Clean Architecture&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;No entanto, analisando criticamente os projetos nos quais atuei e que fazem uso da &lt;em&gt;Clean Architecture&lt;/em&gt; como ferramenta para organização de software, me parece que há uma compreensão parcial sobre o uso do conceito aplicado as estruturas de aplicações. &lt;/p&gt;

&lt;p&gt;Muito embora a obra apresente algumas estratégias de organização de software e ser explicita que elas se aplicam a soluções monolíticas, é perceptível que há uma certa incoerência ao depararmos com várias aplicações adotando apenas uma das estratégias (a mais criticada pelo Uncle Bob, por sinal) e em todo tipo de projeto.  &lt;/p&gt;

&lt;p&gt;O irônico é que no último capítulos do livro, "O capítulo perdido"(34), o Uncle Bob, fazendo uso de toda sua experiência, alerta:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Todas as orientações que você já leu até agora certamente o ajudarão a projetar softwares melhores [...] Mas acontece que o diabo está nos detalhes de implementação, e é realmente muito fácil cair no último obstáculo se você não pensar nisso um pouco também.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como ocorre em outros temas na indústria de software, uma grande parcela dos profissionais não visitam as fontes originais de um determinado conhecimento e consomem indiretamente novos conceitos assumindo como verdade aquilo que alguns gurus lhes transmitiu.&lt;/p&gt;

&lt;p&gt;Diante disso, esse artigo irá apresentar as estratégias de organização propostas no capítulo 34 do &lt;em&gt;Clean Architecture&lt;/em&gt;, e em seguida fará uma breve avaliação sobre a visão apresentada pelo Uncle Bob.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. DESIGN E ORGANIZAÇÃO DE CÓDIGO
&lt;/h2&gt;

&lt;p&gt;O último capítulo, "O capítulo perdido" (34), da última parte (VI) do livro &lt;em&gt;Clean Architecture&lt;/em&gt; apresenta quatro abordagens dedicadas ao design e organização do código. As abordagens são: (a) Pacote por camada, (b) Pacote por recurso, (c) Portas e Adaptadores; e (d) Pacotes por componente. A seguir detalharemos cada uma dessas estratégias.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pacote por camada
&lt;/h3&gt;

&lt;p&gt;Para Uncle Bob, a estratégia de pacotes por camada é uma das abordagens mais tradicionais. Nelas as camadas devem depender apenas da próxima camada adjacente mais baixa. &lt;/p&gt;

&lt;p&gt;Uma das vantagens em adota-la é a rapidez para fazer algo funcionar. Por outro lado, rapidamente as três camadas se mostram insuficientes para conter uma complexidade crescente. Além disso, a estrutura de camadas não expressa nada sobre o domínio de negócio. A figura a seguir ilustra esse modelo de organização.&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%2Faw8dsv31jooxnc1mh3sn.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%2Faw8dsv31jooxnc1mh3sn.png" alt="package by package"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;b&gt;Figura.&lt;/b&gt; representação da estratégia de pacotes por camada (própria)&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pacote por recurso
&lt;/h3&gt;

&lt;p&gt;A estratégia de pacote por recurso é uma divisão vertical, com base em recursos relacionados a conceitos de domínio e Agregações (&lt;em&gt;Aggreate Roots&lt;/em&gt;). Nesse modelo, todos os tipos são colocados em um único pacote. &lt;/p&gt;

&lt;p&gt;Essa abordagem pode ser conhecida também como &lt;em&gt;Vertial Slice Architecture&lt;/em&gt; e tem contornos bem particulares e interessantes na perspectiva de &lt;a href="https://www.jimmybogard.com/vertical-slice-architecture/" rel="noopener noreferrer"&gt;Jimmy Bogard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para Uncle Bob, a vantagem dessa estratégia é que ela "grita" algo sobre o domínio de negócio. Em contrapartida, ele é muito vago sobre as desvantagens, se limitando a dizer: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Se você leu este livro até aqui, deve estar pensando que podemos fazer muito melhor - e está certo!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A figura a seguir ilustra o modelo de organização de pacote por recurso.&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%2F4w2r2vbgv8hhubmvlldu.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%2F4w2r2vbgv8hhubmvlldu.png" alt="package by resource"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;b&gt;Figura.&lt;/b&gt; representação da estratégia de pacotes por recurso (própria)&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Portas e Adaptadores
&lt;/h3&gt;

&lt;p&gt;A estratégia de portas e adaptadores é rapidamente apresentada por Uncle Bob, que afirma que o objetivo dessa abordagem é criar arquiteturas onde o código de domínio é independente e separado de detalhes de implementação, como acessos a banco de dados. &lt;/p&gt;

&lt;p&gt;Também é conhecida como &lt;a href="https://alistair.cockburn.us/hexagonal-architecture/" rel="noopener noreferrer"&gt;Arquitetura Hexagonal&lt;/a&gt;. A figura a seguir ilustra o modelo de organização de portas e adaptadores.&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%2F0wpbbx0wehgggo8nljiy.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%2F0wpbbx0wehgggo8nljiy.png" alt="ports and adapters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;b&gt;Figura.&lt;/b&gt; representação da estratégia de portas e adaptadores (própria)&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Nos últimos anos, esse é o tipo de estrutura mais recorrente que identifico nos projetos. O mais estranho é que mesmo em aplicações que possuam apenas um escopo - e nem precisa ser de negócio, essa estrutura pôde ser identificada. &lt;/p&gt;

&lt;p&gt;Na maioria dos casos, esse tipo de implementação em soluções dotnet apresenta um certo relaxamento na relação entre as camadas de apresentação e infraestrutura, ao permitir que detalhes de implementação de infra vazem durante a injeção de dependências, quando orquestrada pela camada web. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pacote por componente
&lt;/h3&gt;

&lt;p&gt;A estratégia de pacote por componente é nitidamente a abordagem que parece ter a maior empatia de Uncle Bob, uma vez que ela é uma abordagem híbrida que contempla as demais estratégias. &lt;/p&gt;

&lt;p&gt;Essa abordagem agrupa todas as responsabilidades relacionadas a um único componente de alta granularidade, mantendo as interfaces de usuários separadas desse único pacote.&lt;/p&gt;

&lt;p&gt;Na concepção do autor, podemos "pensar nos componentes bem definidos de uma aplicação monolítica como um degrau rumo a uma arquitetura de microsserviços". &lt;/p&gt;

&lt;p&gt;Esse pensamento me remete a uma prática emergente denominada como &lt;a href="https://awesome-architecture.com/modular-monolith/" rel="noopener noreferrer"&gt;Modular Monolith&lt;/a&gt;. A figura a seguir ilustra o modelo de organização de pacote por componente.&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%2Frzj969qz5m1c7g5f7xwx.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%2Frzj969qz5m1c7g5f7xwx.png" alt="package by components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;b&gt;Figura.&lt;/b&gt; representação da estratégia de pacotes por componente (própria)&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Colocando em perspectiva todas as estratégias de organização propostas pela &lt;em&gt;Clean Architecture&lt;/em&gt; podemos ter a seguinte visão comparativa ilustrada na figura a seguir.&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%2F9e14l03qcfje4zeqe9u9.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%2F9e14l03qcfje4zeqe9u9.png" alt="all strategies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;b&gt;Figura.&lt;/b&gt; visão comparativa das estratégias (própria)&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Diante das abordagens apresentadas, é preciso questionar o quanto as equipes ponderam e racionalizam sobre as decisões de design na hora de construir aplicações? Será que as equipes tem adotado a &lt;em&gt;Clean Architecture&lt;/em&gt; apenas como um template de código na busca de organização?&lt;/p&gt;

&lt;p&gt;É preciso reforçar que a &lt;em&gt;Clean Architecture&lt;/em&gt; não contempla a arquitetura de software como um todo. Na verdade ela representa apenas uma das atividades dentro da etapa de &lt;em&gt;Architectural Design&lt;/em&gt; no ciclo de vida da Arquitetura de Software. Para entender mais sobre esse ciclo, recomendo a leitura do livro &lt;a href="https://www.oreilly.com/library/view/designing-software-architectures/9780134390857/" rel="noopener noreferrer"&gt;Designing Software Architectures: A Practical Approach&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. PONDERAÇÕES SOBRE A CLEAN ARCHITECTURE E SEU AUTOR
&lt;/h2&gt;

&lt;p&gt;Embora a intenção seja promover a flexibilidade, a estrutura proposta pela &lt;em&gt;Clean Architecture&lt;/em&gt; pode, paradoxalmente, resultar em rigidez. Alguns críticos argumentam que aderir estritamente a essas regras pode dificultar a adaptação a requisitos de projetos específicos, novas tecnologias ou métodos de desenvolvimento emergentes. O próprio Uncle Bob alerta: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Leave options open where applicable, but be pragmatic, and take into consideration the size of your team, their skill level, and the complexity of the solution in conjunction with your time and budgetary constraints.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Outra crítica comum é que a &lt;em&gt;Clean Architecture&lt;/em&gt; pode levar ao overengineering, onde o esforço para manter o software "limpo" supera os benefícios práticos. Isso pode desviar o foco de entregar funcionalidades valiosas para o usuário final para se concentrar excessivamente na estrutura interna do código.&lt;/p&gt;

&lt;p&gt;É importante ter em mente que o Uncle Bob é uma figura controversa. Suas obras são cheias de afirmações fortes e que precisam ser ponderadas ao lê-las. Existem capítulos inteiros no &lt;em&gt;Clean Architecture&lt;/em&gt; que podem ser contestados à luz da ciência e de pesquisas já validadas antes mesmo da obra ser lançada.&lt;/p&gt;

&lt;p&gt;No entanto, é inegavel sua contribuição à indústria e seu poder de engajamento na comunidade de desenvolvedores. Sua larga experiência e senso pragmático aguçado criaram conceitos cujos benefícios já foram igualmente atestados &lt;a href="https://sol.sbc.org.br/index.php/cbsoft_estendido/article/view/14620/14465" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;&lt;a href="https://link.springer.com/chapter/10.1007/978-3-031-47372-2_8" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Como em qualquer metodologia ou padrão de design, é importante avaliar as necessidades específicas do projeto e o contexto para determinar a abordagem mais apropriada.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. CONCLUSÃO
&lt;/h2&gt;

&lt;p&gt;O artigo aborda a evolução das práticas de engenharia de software, com foco na &lt;em&gt;Clean Architecture&lt;/em&gt; de Robert C. Martin (Uncle Bob), ressaltando a importância de adaptar os princípios de design ao contexto específico de cada projeto. Ele critica a adoção superficial da &lt;em&gt;Clean Architecture&lt;/em&gt;, que muitas vezes resulta em complexidade desnecessária ou overengineering, e destaca a necessidade de uma reflexão crítica sobre as decisões de design.&lt;/p&gt;

&lt;p&gt;Além disso, aponta para a relevância de considerar as características únicas de cada equipe e projeto ao aplicar conceitos como Pacote por Camada, Pacote por Recurso, Portas e Adaptadores, e Pacote por Componente. Também enfatiza a figura controversa de Uncle Bob, reconhecendo suas contribuições, mas também alertando para a necessidade de questionar e ponderar suas afirmações.&lt;/p&gt;

&lt;p&gt;Em resumo, defende uma abordagem pragmática e adaptável ao design de software, priorizando soluções que atendam às necessidades reais dos projetos e promovam uma linguagem de negócio clara e uma arquitetura sustentável, além de enfatizar a importância de ir além dos templates e regras predefinidas para alcançar uma verdadeira valorização do software para os usuários finais.&lt;/p&gt;




&lt;p&gt;Caros leitores,&lt;/p&gt;

&lt;p&gt;Espero que tenham encontrado insights valiosos na discussão sobre o design e organização de código.&lt;/p&gt;

&lt;p&gt;Se você já experimentou essas estratégias em seus projetos, como foi? Quais vantagens e obstáculos você encontrou? Se ainda não tentou, consideraria implementá-la após essa leitura?&lt;/p&gt;

&lt;p&gt;Seu feedback é crucial para enriquecer essa discussão.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>architecture</category>
      <category>cleanarchitecture</category>
    </item>
    <item>
      <title>Por que "tudo junto" é separado e "separado" é tudo junto? Ou... divagações sobre estrutura de testes em .NET</title>
      <dc:creator>Yan Justino</dc:creator>
      <pubDate>Fri, 09 Feb 2024 19:30:45 +0000</pubDate>
      <link>https://dev.to/yanjustino/tudo-junto-e-separado-ou-separado-e-tudo-junto-divagacoes-sobre-estrutura-de-testes-em-net-4kmf</link>
      <guid>https://dev.to/yanjustino/tudo-junto-e-separado-ou-separado-e-tudo-junto-divagacoes-sobre-estrutura-de-testes-em-net-4kmf</guid>
      <description>&lt;p&gt;&lt;strong&gt;YAN JUSTINO&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://repositorio.ufrn.br/handle/123456789/26370"&gt;MSc. Software Engineering&lt;/a&gt; · &lt;a href="https://www.cesar.school/doutorado-profissional-em-engenharia-de-software/"&gt;PhD. Student&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youracclaim.com/users/yan-justino/badges"&gt;AWS&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges"&gt;MCSD&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges"&gt;OCA&lt;/a&gt; · &lt;a href="https://orcid.org/0000-0001-7248-716X"&gt;ORCID&lt;/a&gt;  · &lt;a href=""&gt;Tech Lead at ITAÚ Unibanco&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gGFm_TiW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/demo-tests-F6A506%3Fstyle%3Dfor-the-badge" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gGFm_TiW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/demo-tests-F6A506%3Fstyle%3Dfor-the-badge" alt="Static Badge" width="123" height="28"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;em&gt;Atualizado em 10/02/2024&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Design de Software&lt;/strong&gt; é uma disciplina que procura diminuir a carga cognitiva entre software e os problemas do "mundo real". Muitos conceitos e técnicas podem ser aplicados ao código a fim de se alcançar essa capacidade. Partindo da perspectiva de um desenvolvedor, penso que o design pode se manifestar como uma espécie de "estética" que evidência um fluxo coeso da informação, estruturado em uma visão de solução. Particularmente, gosto quando o código transmite aquele senso de "beleza" que nos faz exclamar: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Uau! Que código bem escrito!!!!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Focando em um recorte específico da organização de código, tenho, por experiência, a impressão de que a qualidade estética aplicada aos artefatos do código de produção (&lt;em&gt;src&lt;/em&gt;) não é proporcional a aplicada aos artefatos de testes. Revisitando o passado, percebo que em diversos projetos que pude atuar, havia uma certa falta de "apreço" com a escrita e manutenção dos testes. &lt;/p&gt;

&lt;p&gt;Independentemente da sênioridade dos desenvolvedores, e da relevância do projeto, os testes seguiam seu destino cruel em uma jornada rumo a "cafonice". Recorrendo a um &lt;em&gt;MEA CULPA&lt;/em&gt;, eu também fui responsável ao longo de minha carreira, por escrever diversas bizarrices em forma de testes (Quem nunca?). Diante disso, uma pulga atrás orelha me faz pensar na seguinte questão:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como aspectos culturais somados a algumas estratégias de design impactam a evolução do código de teste?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essa não é uma pergunta simples e talvez mereça uma investigação mais profunda do que essas divagações. Guiado por um impulso extremamente pragmático, direciono a atenção para algumas estratégias de design para entender: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como as linguagens e frameworks organizam seus softwares de modo a facilitar a manutenção concomitante do código de produção e do código de testes?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Diante disso, me deparei com um tradeoff bem interessante: &lt;strong&gt;distanciamento vs aproximação "física" entre o código de testes e o código de produção&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Distanciamento vs Aproximação
&lt;/h2&gt;

&lt;p&gt;Enquanto desenvolvedor &lt;em&gt;dotnet&lt;/em&gt;, frequentemente atuo em sistemas que adotam como estratégia o uso de projetos distintos dentro da mesma solução para separar os testes do código de produção. Acredito que essa seja a prática mais comum e &lt;a href="https://gist.github.com/davidfowl/ed7564297c61fe9ab814"&gt;recomendada&lt;/a&gt; no mundo dotnet. O modelo a seguir ilustra um exemplo de estrutura de solução dotnet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$/
├─ src/
│  ├─ Production.csproj
│     ├─ ProductionCode.cs
├─ tests/
│  ├─ UnitTests.csproj
│     ├─ TesteCode.cs
├─ .gitignore
├─ README.md
├─ Solution.sln

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

&lt;/div&gt;



&lt;p&gt;Contudo, tomando por referência outras Linguagens e Frameworks percebe-se uma abordagem diferente: o código de teste é colocado próximo (na mesma pasta ou arquivo) ao o código de produção, como comumente feito em &lt;a href="https://go.dev/doc/modules/layout#basic-package"&gt;Go&lt;/a&gt; e &lt;a href="https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html"&gt;Rust&lt;/a&gt;. O modelo a seguir ilustra como um pacote básico do Go é estruturado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$/
├─ src/
│  ├─ go.mod
│  ├─ modname.go
│  ├─ modname_test.go
├─ .gitignore
├─ README.md

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

&lt;/div&gt;



&lt;p&gt;Vasculhando a rede sobre essa abordagem, percebi um certo pensamento comum entre seus defensores: de que juntar o código de teste ao código de produção pode oferece algumas vantagens para o processo de desenvolvimento e a manutenibilidade do código. Dentre esses benefícios, eles alegam que a abordagem promove: (a) facilidade de Localização, (b) encorajamento a escrita de testes, (c) colaboração, (d) rápida refatoração, (e) estrutura uniforme etc.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Tá... Mas e o C#?
&lt;/h2&gt;

&lt;p&gt;Diante dos potênciais benefícios em aproximar os arquivos de testes com os arquivos de produção, podemos nos perguntar &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quais seriam os ganhos e limitações dessa abordagem aplicada em uma solução dotnet? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tendo essa questão em mente, convido a darmos um passo desprendido de qualquer pré-conceito para aguçar nosso senso de curiosidade. Para isso, nosso ponto de partida será aplicar a abordagem de unificar o arquivo de testes ao código de produção em um mesmo projeto dotnet. As etapas a seguir detalharão como faremos isso.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Criando a solução
&lt;/h3&gt;

&lt;p&gt;Diferentemente, de uma solução prototípica em dotnet onde teríamos um projeto de testes apartado, optamos por não criá-lo, e passamos a escrever nossos arquivos de testes diretamente no projeto de produção, fazendo uso da convenção &lt;code&gt;*.Test.cs&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$/
├─ src/
│  ├─ OrderManagement.csproj/
│     ├─ Order/
│        ├─ OrderItem.cs
│        ├─ OrderItem.Test.cs
├─ .gitignore
├─ README.md
├─ Solution.sln

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Configurando o projeto
&lt;/h3&gt;

&lt;p&gt;O próximo passo é adicionar ao projeto, os pacotes relativos a execução dos testes. Nesse ponto, o projeto recebeu as referências aos os pacotes do framework &lt;em&gt;xUnit&lt;/em&gt;, para executar os testes; e o FluentAssertions, para proporcionar uma maior expressividade as validações. como ilustrar o código de configuração a seguir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;OutputType&amp;gt;&lt;/span&gt;Exe&lt;span class="nt"&gt;&amp;lt;/OutputType&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;net8.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ImplicitUsings&amp;gt;&lt;/span&gt;enable&lt;span class="nt"&gt;&amp;lt;/ImplicitUsings&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Nullable&amp;gt;&lt;/span&gt;enable&lt;span class="nt"&gt;&amp;lt;/Nullable&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;


    &lt;span class="nt"&gt;&amp;lt;ItemGroup&lt;/span&gt; &lt;span class="na"&gt;Label=&lt;/span&gt;&lt;span class="s"&gt;"Test Dependecies"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Test.Sdk"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"17.6.0"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"xunit"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"2.4.2"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"FluentAssertions"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"6.12.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"xunit.runner.visualstudio"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"2.4.5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;IncludeAssets&amp;gt;&lt;/span&gt;runtime; build; native; contentfiles; analyzers; buildtransitive&lt;span class="nt"&gt;&amp;lt;/IncludeAssets&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;PrivateAssets&amp;gt;&lt;/span&gt;all&lt;span class="nt"&gt;&amp;lt;/PrivateAssets&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/PackageReference&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"coverlet.collector"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"6.0.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;IncludeAssets&amp;gt;&lt;/span&gt;runtime; build; native; contentfiles; analyzers; buildtransitive&lt;span class="nt"&gt;&amp;lt;/IncludeAssets&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;PrivateAssets&amp;gt;&lt;/span&gt;all&lt;span class="nt"&gt;&amp;lt;/PrivateAssets&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/PackageReference&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Escrevendo o Teste de Unidade
&lt;/h3&gt;

&lt;p&gt;Criamos um arquivo chamado &lt;code&gt;OrdemItem.cs&lt;/code&gt; contendo o código de um &lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/records"&gt;record&lt;/a&gt; chamado &lt;code&gt;OrdemItem&lt;/code&gt;. Fizemos uso de um recurso da linguagem C# chamado &lt;a href="https://learn.microsoft.com/pt-br/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods"&gt;&lt;code&gt;partial&lt;/code&gt;&lt;/a&gt; para dividir os escopos das regras de negócio dos seus testes. O código a seguir ilustra essa implementação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;OrderItem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;Sku&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="nf"&gt;GetTotalPrice&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;operator&lt;/span&gt; &lt;span class="nf"&gt;OrderItem&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Sku&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGuid&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código a seguir, ilustrar o conteúdo do arquivo &lt;code&gt;OrderItem.Test.cs&lt;/code&gt;, o qual implementa as especificações do framework de testes &lt;em&gt;xUnit&lt;/em&gt;, para testar o record OrderItem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;OrderItem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Theory&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;InlineData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;005&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;InlineData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;05&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;025&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;InlineData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;250&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;InlineData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;000&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;get_total_price_method_should_calculate_correctly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;OrderItem&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     
        &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetTotalPrice&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Ajustando a compilação
&lt;/h3&gt;

&lt;p&gt;A fim de evitar que a versão final do software leve arquivos e pacotes desnecessários para o ambiente de produção, fizemos as seguintes intervenções no projeto.&lt;/p&gt;

&lt;p&gt;a) adicionamos a tag a seguir, para indicar ao compilador que em versões de release remova os arquivos que estão na convenção &lt;code&gt;**\*.Tests.cs&lt;/code&gt;. Isso irá remover da solução todos os arquivos de teste.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ItemGroup&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"'$(Configuration)' == 'Release'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;Compile&lt;/span&gt; &lt;span class="na"&gt;Remove=&lt;/span&gt;&lt;span class="s"&gt;"**\*.Tests.cs"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;b) incluímos a condicional &lt;code&gt;'$(Configuration)' != 'Release'&lt;/code&gt; na tag que envolve nossas dependências de testes, para indicar ao compilador que as utilize apenas em versões de desenvolvimento.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ItemGroup&lt;/span&gt; &lt;span class="na"&gt;Label=&lt;/span&gt;&lt;span class="s"&gt;"Test Dependecies"&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"'$(Configuration)' != 'Release'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A versão final de nosso arquivo de projeto ficou da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Sdk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;OutputType&amp;gt;&lt;/span&gt;Exe&lt;span class="nt"&gt;&amp;lt;/OutputType&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;net8.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ImplicitUsings&amp;gt;&lt;/span&gt;enable&lt;span class="nt"&gt;&amp;lt;/ImplicitUsings&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Nullable&amp;gt;&lt;/span&gt;enable&lt;span class="nt"&gt;&amp;lt;/Nullable&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ItemGroup&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"'$(Configuration)' == 'Release'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Compile&lt;/span&gt; &lt;span class="na"&gt;Remove=&lt;/span&gt;&lt;span class="s"&gt;"**\*.Tests.cs"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ItemGroup&lt;/span&gt; &lt;span class="na"&gt;Label=&lt;/span&gt;&lt;span class="s"&gt;"Test Dependecies"&lt;/span&gt; &lt;span class="na"&gt;Condition=&lt;/span&gt;&lt;span class="s"&gt;"'$(Configuration)' != 'Release'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.NET.Test.Sdk"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"17.6.0"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"xunit"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"2.4.2"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"FluentAssertions"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"6.12.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"xunit.runner.visualstudio"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"2.4.5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;IncludeAssets&amp;gt;&lt;/span&gt;runtime; build; native; contentfiles; analyzers; buildtransitive&lt;span class="nt"&gt;&amp;lt;/IncludeAssets&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;PrivateAssets&amp;gt;&lt;/span&gt;all&lt;span class="nt"&gt;&amp;lt;/PrivateAssets&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/PackageReference&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"coverlet.collector"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"6.0.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;IncludeAssets&amp;gt;&lt;/span&gt;runtime; build; native; contentfiles; analyzers; buildtransitive&lt;span class="nt"&gt;&amp;lt;/IncludeAssets&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;PrivateAssets&amp;gt;&lt;/span&gt;all&lt;span class="nt"&gt;&amp;lt;/PrivateAssets&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/PackageReference&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Executando os testes
&lt;/h3&gt;

&lt;p&gt;Com a implementação dos passos anteriores, somos capazes de executar nosso teste diretamente no projeto principal, através do comando &lt;code&gt;dotnet test&lt;/code&gt; ou pelos recursos da IDE (no meu caso o &lt;a href="https://www.jetbrains.com/rider/"&gt;Rider&lt;/a&gt;).&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Avaliações
&lt;/h2&gt;

&lt;p&gt;Diante da implementação apresentada, concluímos que não existem empecilhos para um teste conviver junto ao seu código de produção em um projeto dotnet. Percebemos que a adoção do recurso &lt;code&gt;partial&lt;/code&gt; possibilita um certo isolamento do teste em nível lógico, e ao mesmo tempo lhe concede um acesso a todo o escopo de visibilidade do código de produção. &lt;/p&gt;

&lt;p&gt;Outro aspecto que nos chama atenção é que o uso da convenção &lt;code&gt;**\*.Tests.cs&lt;/code&gt; permite uma ordenação "natural" na árvore de arquivos do projeto. Isso facilita a localização do arquivo de testes e pode ser um incentivo para desenvolvedores mante-los organizados. Essa convenção facilita adaptações no processo de compilação para remover os arquivos de testes quando forem enviados para um ambiente produtivo.&lt;/p&gt;

&lt;p&gt;Pensando em aspectos de &lt;a href="https://github.blog/2023-06-08-developer-experience-what-is-it-and-why-should-you-care/"&gt;developer experience&lt;/a&gt;, sinto um grande conforto e uma sensação de praticidade ao ver os testes tão próximos ao código de produção. Tendo a acreditar que a abordagem tem potencial de favorecer o processo de construção e manutenibilidade de software de forma concomitante aos testes. Contudo, algumas ponderações devem ser feitas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações Importantes
&lt;/h2&gt;

&lt;p&gt;Alguns aspectos devem ser considerados sobre a adoção dessa abordagem em soluções dotnet:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A abordagem parece ser apropriada para Testes de Unidade. Sendo assim, recomendamos que testes de integração e end-to-end (E2E) mantenham suas estruturas apartadas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Existe uma carga extra sobre compilador para remover os artefatos de testes do código de produção. Soluções que contenham muitos projetos podem ser impactadas em desempenho. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;É preciso investigar o quanto a adoção da abordagem pode impactar as esteiras de pipeline em sua organização. Adaptações nos steps podem ser necessárias.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Analisadores estáticos de código como o &lt;a href="https://en.wikipedia.org/wiki/SonarQube"&gt;SonarQube&lt;/a&gt; podem apontar problemas para esse tipo de estrutura em soluções dotnet. O escopo desse artigo não explorou essa vertente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;É preciso ponderar se a abordagem trará um benefício real para a equipe. O engajamento a essa abordagem deve estar associada á um ganho real para a equipe e organização.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;De forma geral, a abordagem parece ser muito promissora para o uso em testes de unidade. Contudo, em muitos casos, seguir as convenções da comunidade e as melhores práticas para a linguagem pode ajudar a manter o código organizado, facilitar a manutenção e melhorar a colaboração entre desenvolvedores. Nesse sentido, é preciso balancear os ganhos e limitação na aplicação de qualquer nova técnica.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O texto explora a prática de colocar arquivos de teste na mesma pasta que o código de produção, destacando os benefícios dessa abordagem, como facilidade de localização, incentivo à escrita de testes, e facilidade de refatoração. Além disso, compara essa prática, comum em linguagens como Go e Rust, com a separação tradicional de testes e código de produção em projetos C#.&lt;/p&gt;

&lt;p&gt;Para isso, foi conduzida uma experiência em .NET usando *.Test.cs e partial classes para demonstrar a viabilidade e vantagens de manter testes próximos ao código. Apesar dos benefícios percebidos, como praticidade e organização melhorada, o texto pondera sobre desafios potenciais, como impacto no compilador e adaptações na pipeline de CI/CD. Ele conclui que, embora tecnicamente viável, a adoção dessa abordagem deve considerar as práticas da comunidade e as necessidades específicas do projeto&lt;/p&gt;




&lt;p&gt;Caros leitores,&lt;/p&gt;

&lt;p&gt;Espero que tenham encontrado insights valiosos na discussão sobre a co-localização de arquivos de teste e código de produção, uma prática que pode transformar significativamente o desenvolvimento de software.&lt;/p&gt;

&lt;p&gt;Se você já experimentou essa metodologia em seus projetos, como foi? Quais vantagens e obstáculos você encontrou? Se ainda não tentou, consideraria implementá-la após essa leitura?&lt;/p&gt;

&lt;p&gt;Seu feedback é crucial para enriquecer essa discussão. &lt;/p&gt;

&lt;p&gt;O código desse artigo está disponível &lt;a href="https://github.com/yanjustino/test-and-production-code-in-the-same-directory/tree/main"&gt;Aqui&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Testes de integração potencializados por EF, docker e TestContainer</title>
      <dc:creator>Yan Justino</dc:creator>
      <pubDate>Sat, 04 Nov 2023 19:12:56 +0000</pubDate>
      <link>https://dev.to/yanjustino/testes-de-integracao-potencializados-por-ef-docker-e-testcontainer-18fh</link>
      <guid>https://dev.to/yanjustino/testes-de-integracao-potencializados-por-ef-docker-e-testcontainer-18fh</guid>
      <description>&lt;p&gt;&lt;strong&gt;YAN JUSTINO&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://repositorio.ufrn.br/handle/123456789/26370"&gt;MSc. Software Engineering&lt;/a&gt; · &lt;a href="https://www.cesar.school/doutorado-profissional-em-engenharia-de-software/"&gt;PhD. Student&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youracclaim.com/users/yan-justino/badges"&gt;AWS&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges"&gt;MCSD&lt;/a&gt; · &lt;a href="https://www.youracclaim.com/users/yan-justino/badges"&gt;OCA&lt;/a&gt; · &lt;a href="https://orcid.org/0000-0001-7248-716X"&gt;ORCID&lt;/a&gt;  · &lt;a href=""&gt;Tech Lead at ITAÚ Unibanco&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Este artigo foi escrito originalmente em &lt;strong&gt;04 de Novembro de 2023&lt;/strong&gt;. Ele foi revisado e, é importante lembrar que, ele representa uma visão da época em que foi escrito&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gGFm_TiW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/demo-tests-F6A506%3Fstyle%3Dfor-the-badge" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gGFm_TiW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://img.shields.io/badge/demo-tests-F6A506%3Fstyle%3Dfor-the-badge" alt="Static Badge" width="123" height="28"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;Sim, o desenvolvedor gastará boa parte do seu tempo escrevendo código de testes. Mas isso não quer dizer que ele seja menos produtivo por causa disso - &lt;strong&gt;Mauricio aniche&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nessa demo adentramos no universo das práticas modernas de desenvolvimento de software para explorar como o uso estratégico de Entity Framework, Docker e TestContainer pode revolucionar seus processos de testes de integração. &lt;/p&gt;

&lt;p&gt;À medida que a tecnologia evolui, nossas metodologias também precisam evoluir, e ao adotar essas ferramentas, podemos aprimorar a produtividade, confiabilidade e a qualidade geral de nossos projetos de software. &lt;/p&gt;

&lt;p&gt;Acompanhem-me enquanto percorremos os benefícios que essas tecnologias oferecem e descubram como elas podem elevar seu processo de desenvolvimento a novas alturas. Aproveite o vídeo e compartilhe se gostar...&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://www.youtube.com/watch?si=XXT3U4_u0xxONE43&amp;amp;v=qUP4FO4vVZ4&amp;amp;feature=youtu.be" 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--f1r4CkAH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.ytimg.com/vi/qUP4FO4vVZ4/hqdefault.jpg" height="360" class="m-0" width="480"&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://www.youtube.com/watch?si=XXT3U4_u0xxONE43&amp;amp;v=qUP4FO4vVZ4&amp;amp;feature=youtu.be" rel="noopener noreferrer" class="c-link"&gt;
          Testes de integração potencializados por EF, docker e TestContainer - YouTube
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Hoje, vamos adentrar o universo das práticas modernas de desenvolvimento de software e explorar como o uso estratégico de Entity Framework, Docker e TestCont...
        &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--4HZrg87d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.youtube.com/s/desktop/7ea5dfab/img/favicon.ico" width="16" height="16"&gt;
        youtube.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&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/yanjustino"&gt;
        yanjustino
      &lt;/a&gt; / &lt;a href="https://github.com/yanjustino/sql-sartuday-es"&gt;
        sql-sartuday-es
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Demo para evento SQL Sartuday / ES - 2023
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  CONTEXTUALIZANDO...
&lt;/h2&gt;

&lt;p&gt;Essa demo é resultado da minha última participação em eventos presenciais: o SQL Sartuday, realizado no sádado dia 28/10/2023. Muitas pessoas me pediram o link da gravação. Infelizmente o evento não registrou as palestras. Sendo assim, decidi gravar o conteúdo da palestra e disponibiliza-lo no canal "Academia .net para zumbis". &lt;/p&gt;

&lt;p&gt;Essa canal, com 1.5K de inscritos, é muito especial para mim e estou feliz em poder trazer novos conteúdos para ele. O desejo é reativá-lo e poder contribuir mais com a comunidade.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
