<?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: Gabriel Bertonsin</title>
    <description>The latest articles on DEV Community by Gabriel Bertonsin (@gabriel_berton_brito).</description>
    <link>https://dev.to/gabriel_berton_brito</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4122667%2Fd8a0f1d9-b657-4fbe-8272-35e3f795aad0.jpg</url>
      <title>DEV Community: Gabriel Bertonsin</title>
      <link>https://dev.to/gabriel_berton_brito</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gabriel_berton_brito"/>
    <language>en</language>
    <item>
      <title>Quebrando de Propósito: Como o ChaosEngineeringMasterDeck Transformou Falhas em Confiança na Nossa Arquitetura</title>
      <dc:creator>Gabriel Bertonsin</dc:creator>
      <pubDate>Sat, 24 Oct 2026 18:58:03 +0000</pubDate>
      <link>https://dev.to/gabriel_berton_brito/quebrando-de-proposito-como-o-chaosengineeringmasterdeck-transformou-falhas-em-confianca-na-nossa-hje</link>
      <guid>https://dev.to/gabriel_berton_brito/quebrando-de-proposito-como-o-chaosengineeringmasterdeck-transformou-falhas-em-confianca-na-nossa-hje</guid>
      <description>&lt;p&gt;Era uma sexta-feira, 18h47. O dashboard estava verde, o deploy da semana tinha passado sem sustos e metade do time já pensava no fim de semana. Foi exatamente nesse momento que um dos nossos microsserviços começou a responder em 4 segundos em vez de 80 milissegundos. Nenhum servidor caiu. Nenhum alerta de "serviço fora do ar" disparou. Mesmo assim, em menos de três minutos, o checkout inteiro da plataforma estava travado.&lt;/p&gt;

&lt;p&gt;A boa notícia: &lt;strong&gt;isso não aconteceu em um incidente real.&lt;/strong&gt; Aconteceu porque nós mesmos provocamos — de forma controlada, com hipótese escrita, métricas monitoradas e um botão de abortar ao alcance da mão. E foi uma das descobertas mais valiosas que fizemos naquele trimestre.&lt;/p&gt;

&lt;p&gt;Neste artigo, vou mostrar como nossa equipe usa o &lt;strong&gt;ChaosEngineeringMasterDeck&lt;/strong&gt; — um baralho de experimentos de caos que criamos para tornar a engenharia de resiliência sistemática, repetível e (por que não?) divertida.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Introdução ao Chaos Engineering
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 O que é, afinal?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Chaos Engineering&lt;/strong&gt; é a disciplina de &lt;em&gt;experimentar&lt;/em&gt; em um sistema distribuído para construir confiança na sua capacidade de suportar condições turbulentas em produção. O termo ganhou força com a Netflix por volta de 2010, quando a empresa migrou para a AWS e criou o famoso &lt;strong&gt;Chaos Monkey&lt;/strong&gt;, uma ferramenta que desligava instâncias aleatoriamente durante o horário comercial.&lt;/p&gt;

&lt;p&gt;A ideia parece absurda à primeira vista: por que alguém desligaria seus próprios servidores? A resposta é simples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Em sistemas distribuídos, a falha é uma certeza, não uma possibilidade.&lt;/strong&gt; Redes têm latência, discos enchem, zonas de disponibilidade caem, dependências externas ficam lentas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testes tradicionais validam o que você já sabe.&lt;/strong&gt; Testes unitários e de integração verificam comportamentos &lt;em&gt;esperados&lt;/em&gt;. O caos revela comportamentos &lt;em&gt;emergentes&lt;/em&gt; — aqueles que surgem da interação entre dezenas de componentes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;É melhor descobrir uma fraqueza às 14h de uma terça-feira, com o time inteiro preparado, do que às 3h da manhã de um domingo, com clientes reclamando.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.2 Os princípios fundamentais
&lt;/h3&gt;

&lt;p&gt;O manifesto &lt;a href="https://principlesofchaos.org" rel="noopener noreferrer"&gt;Principles of Chaos Engineering&lt;/a&gt; define a base que seguimos à risca:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Construa uma hipótese em torno do estado estável&lt;/strong&gt; (&lt;em&gt;steady state&lt;/em&gt;). Em vez de olhar para métricas internas (CPU, memória), defina o comportamento normal pelo que importa ao negócio: pedidos por minuto, taxa de sucesso, latência percebida pelo usuário.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Varie eventos do mundo real.&lt;/strong&gt; Simule o que de fato acontece: queda de instâncias, latência de rede, falha de DNS, picos de tráfego.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execute experimentos em produção&lt;/strong&gt; (ou no ambiente mais próximo possível dela). Só a produção tem o tráfego, os dados e as configurações reais.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatize os experimentos para rodar continuamente.&lt;/strong&gt; Resiliência é um alvo móvel — cada deploy pode reintroduzir uma fraqueza.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimize o raio de explosão&lt;/strong&gt; (&lt;em&gt;blast radius&lt;/em&gt;). Comece pequeno, expanda gradualmente.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1.3 A mudança de mentalidade: de evitar falhas para abraçá-las
&lt;/h3&gt;

&lt;p&gt;A engenharia tradicional tenta &lt;strong&gt;prevenir&lt;/strong&gt; falhas a todo custo — o que, em sistemas distribuídos, é uma batalha perdida. A engenharia de resiliência parte de outra premissa:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mentalidade tradicional&lt;/th&gt;
&lt;th&gt;Mentalidade de resiliência&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Nosso sistema não pode cair."&lt;/td&gt;
&lt;td&gt;"Nosso sistema &lt;em&gt;vai&lt;/em&gt; falhar. Como ele se comporta quando isso acontecer?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Foco em MTBF (tempo médio entre falhas)&lt;/td&gt;
&lt;td&gt;Foco em MTTR (tempo médio de recuperação)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incidente = culpa de alguém&lt;/td&gt;
&lt;td&gt;Incidente = oportunidade de aprendizado (&lt;em&gt;blameless&lt;/em&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confiança baseada em esperança&lt;/td&gt;
&lt;td&gt;Confiança baseada em evidência&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Ponto-chave:&lt;/strong&gt; Chaos Engineering &lt;strong&gt;não é&lt;/strong&gt; sair quebrando coisas aleatoriamente. É o &lt;strong&gt;método científico&lt;/strong&gt; aplicado à confiabilidade: hipótese, experimento controlado, observação e conclusão.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. Dissecando o ChaosEngineeringMasterDeck
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 O que é o Master Deck?
&lt;/h3&gt;

&lt;p&gt;Quando começamos a praticar Chaos Engineering, enfrentamos três problemas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os experimentos eram &lt;strong&gt;ad hoc&lt;/strong&gt;: cada engenheiro testava o que lembrava, do jeito que achava melhor.&lt;/li&gt;
&lt;li&gt;Os resultados &lt;strong&gt;se perdiam&lt;/strong&gt; em threads de chat e nunca viravam conhecimento compartilhado.&lt;/li&gt;
&lt;li&gt;O time via o caos como &lt;strong&gt;algo intimidador&lt;/strong&gt;, reservado a "especialistas em SRE".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O &lt;strong&gt;ChaosEngineeringMasterDeck&lt;/strong&gt; nasceu para resolver os três. Ele funciona em três camadas ao mesmo tempo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Framework:&lt;/strong&gt; um catálogo padronizado de experimentos, em que cada "carta" é um modelo completo de teste de falha.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ferramenta gamificada:&lt;/strong&gt; nos nossos &lt;em&gt;Game Days&lt;/em&gt; mensais, o time "compra" cartas do baralho e executa os cenários sorteados, acumulando pontos por fraquezas descobertas e corrigidas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentação viva de incidentes:&lt;/strong&gt; cada execução gera um registro versionado no repositório, e incidentes reais de produção viram novas cartas.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2.2 Os naipes do baralho
&lt;/h3&gt;

&lt;p&gt;As cartas são organizadas em &lt;strong&gt;naipes&lt;/strong&gt;, cada um representando uma categoria de falha:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Naipe&lt;/th&gt;
&lt;th&gt;Categoria&lt;/th&gt;
&lt;th&gt;Exemplos de cartas&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;♠️ &lt;strong&gt;Espadas&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Infraestrutura&lt;/td&gt;
&lt;td&gt;Queda de instância EC2, perda de uma Availability Zone, nó do Kubernetes drenado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;♥️ &lt;strong&gt;Copas&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Rede&lt;/td&gt;
&lt;td&gt;Latência injetada, perda de pacotes, falha de DNS, partição de rede&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;♦️ &lt;strong&gt;Ouros&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Dados e estado&lt;/td&gt;
&lt;td&gt;Banco de dados indisponível, failover de réplica, cache Redis zerado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;♣️ &lt;strong&gt;Paus&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Aplicação e dependências&lt;/td&gt;
&lt;td&gt;Exceções injetadas, API de terceiros fora do ar, exaustão de pool de threads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;O &lt;strong&gt;valor da carta&lt;/strong&gt; indica sua severidade e, consequentemente, o nível de maturidade exigido do time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2 a 5:&lt;/strong&gt; experimentos de baixo impacto, ideais para staging e times iniciantes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;6 a 10:&lt;/strong&gt; experimentos em produção com blast radius limitado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Valete, Dama, Rei:&lt;/strong&gt; cenários compostos (múltiplas falhas simultâneas).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ás:&lt;/strong&gt; desastres regionais — só liberados depois que o time completou as cartas anteriores do mesmo naipe.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 Anatomia de uma carta
&lt;/h3&gt;

&lt;p&gt;Cada carta é um arquivo YAML versionado no Git. Essa estrutura obriga o time a pensar &lt;strong&gt;antes&lt;/strong&gt; de quebrar qualquer coisa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;COPAS-07&lt;/span&gt;
&lt;span class="na"&gt;nome&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Lesma&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;no&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Estoque"&lt;/span&gt;
&lt;span class="na"&gt;naipe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;copas&lt;/span&gt;            &lt;span class="c1"&gt;# rede&lt;/span&gt;
&lt;span class="na"&gt;valor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;                &lt;span class="c1"&gt;# produção com blast radius limitado&lt;/span&gt;

&lt;span class="na"&gt;hipotese&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;Se o inventory-service sofrer 3s de latência adicional,&lt;/span&gt;
  &lt;span class="s"&gt;o checkout continuará concluindo pedidos com taxa de sucesso ≥ 99%&lt;/span&gt;
  &lt;span class="s"&gt;e p99 &amp;lt; 1,5s, pois o circuit breaker abrirá e o fallback&lt;/span&gt;
  &lt;span class="s"&gt;de reserva otimista assumirá.&lt;/span&gt;

&lt;span class="na"&gt;estado_estavel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;metrica&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;taxa_sucesso_checkout&lt;/span&gt;
    &lt;span class="na"&gt;baseline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;99.5%"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;metrica&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latencia_p99_checkout&lt;/span&gt;
    &lt;span class="na"&gt;baseline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;800ms"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;metrica&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pedidos_por_minuto&lt;/span&gt;
    &lt;span class="na"&gt;baseline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;~1.200&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(horário&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;comercial)"&lt;/span&gt;

&lt;span class="na"&gt;variaveis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;independente&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latência&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;de&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;3000ms&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;em&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;100%&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;das&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;respostas&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;do&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;inventory-service"&lt;/span&gt;
  &lt;span class="na"&gt;alvo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pods&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;com&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;label&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;canary=chaos&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(10%&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;do&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tráfego)"&lt;/span&gt;
  &lt;span class="na"&gt;duracao&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;minutos"&lt;/span&gt;

&lt;span class="na"&gt;blast_radius&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ambiente&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;producao&lt;/span&gt;
  &lt;span class="na"&gt;trafego_afetado&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10%&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(pods&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;canary)"&lt;/span&gt;
  &lt;span class="na"&gt;usuarios&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;somente&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;região&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;sa-east-1"&lt;/span&gt;
  &lt;span class="na"&gt;dependencias_protegidas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment-service"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-service"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;condicoes_de_aborto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;taxa_sucesso_checkout&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;97%&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;por&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;mais&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;de&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;60s"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;erros&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;5xx&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;no&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;API&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Gateway&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;2%"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qualquer&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;alerta&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;P1&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;disparado"&lt;/span&gt;

&lt;span class="na"&gt;rollback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kubectl&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;delete&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-f&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;experiments/copas-07-latency.yaml"&lt;/span&gt;
&lt;span class="na"&gt;responsaveis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@time-checkout"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@sre-plantao"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repare que a carta separa claramente os três pilares de um bom experimento:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hipótese:&lt;/strong&gt; uma afirmação falsificável sobre o comportamento do sistema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variáveis:&lt;/strong&gt; o que estamos alterando (variável independente) e onde.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Métricas de controle:&lt;/strong&gt; o estado estável que precisa ser preservado e os limites que disparam o aborto.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Estudo de Caso: a carta "A Lesma no Estoque" (♥️ Copas 7)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 A arquitetura sob teste
&lt;/h3&gt;

&lt;p&gt;Nossa plataforma de e-commerce roda na &lt;strong&gt;AWS&lt;/strong&gt;, em um cluster &lt;strong&gt;Amazon EKS&lt;/strong&gt; distribuído em três Availability Zones da região &lt;code&gt;sa-east-1&lt;/code&gt; (São Paulo). O fluxo de checkout envolve quatro microsserviços em &lt;strong&gt;Spring Boot 3&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         ┌──────────────────┐
   Usuário ──HTTPS──▶    │   API Gateway    │
                         │  (AWS ALB + WAF) │
                         └────────┬─────────┘
                                  │
                         ┌────────▼─────────┐
                         │ checkout-service │  ◀── orquestra o pedido
                         │  (Spring Boot)   │
                         └──┬──────┬─────┬──┘
                            │      │     │
              ┌─────────────┘      │     └──────────────┐
              ▼                    ▼                    ▼
   ┌─────────────────────┐ ┌───────────────┐ ┌──────────────────┐
   │  inventory-service  │ │payment-service│ │  user-service    │
   │   💥 ALVO DO CAOS   │ │               │ │                  │
   └─────────┬───────────┘ └───────┬───────┘ └────────┬─────────┘
             │                     │                  │
     ┌───────▼───────┐     ┌───────▼───────┐  ┌───────▼───────┐
     │ Amazon RDS    │     │ Gateway de    │  │ ElastiCache   │
     │ (PostgreSQL)  │     │ pagamento     │  │ (Redis)       │
     └───────────────┘     └───────────────┘  └───────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;checkout-service&lt;/code&gt; consulta o &lt;code&gt;inventory-service&lt;/code&gt; para reservar o estoque antes de cobrar o cliente. Essa chamada é síncrona e fica no &lt;strong&gt;caminho crítico&lt;/strong&gt; do pedido — o lugar perfeito para uma fraqueza se esconder.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Por que essa carta?
&lt;/h3&gt;

&lt;p&gt;Uma queda total de serviço é relativamente fácil de lidar: a conexão é recusada, o erro é imediato e os mecanismos de fallback disparam. &lt;strong&gt;Latência é mais traiçoeira.&lt;/strong&gt; Um serviço lento não está "fora do ar" — ele segura conexões, ocupa threads e pode propagar a lentidão para todos os serviços que dependem dele. É o que chamamos de &lt;strong&gt;falha em cascata&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Os padrões de resiliência que esperávamos ver
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;checkout-service&lt;/code&gt; usa &lt;strong&gt;Resilience4j&lt;/strong&gt; para proteger a chamada ao estoque:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# application.yml do checkout-service&lt;/span&gt;
&lt;span class="na"&gt;resilience4j&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;circuitbreaker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;inventory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;sliding-window-type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;COUNT_BASED&lt;/span&gt;
        &lt;span class="na"&gt;sliding-window-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
        &lt;span class="na"&gt;failure-rate-threshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;          &lt;span class="c1"&gt;# abre com 50% de falhas&lt;/span&gt;
        &lt;span class="na"&gt;slow-call-duration-threshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1s&lt;/span&gt;    &lt;span class="c1"&gt;# chamada &amp;gt; 1s conta como lenta&lt;/span&gt;
        &lt;span class="na"&gt;slow-call-rate-threshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;        &lt;span class="c1"&gt;# abre com 50% de chamadas lentas&lt;/span&gt;
        &lt;span class="na"&gt;wait-duration-in-open-state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
        &lt;span class="na"&gt;permitted-number-of-calls-in-half-open-state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
  &lt;span class="na"&gt;timelimiter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;inventory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;timeout-duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1500ms&lt;/span&gt;
  &lt;span class="na"&gt;retry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;inventory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;max-attempts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
        &lt;span class="na"&gt;wait-duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;200ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@CircuitBreaker&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"inventory"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fallbackMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"reservaOtimista"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Retry&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"inventory"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ReservaResponse&lt;/span&gt; &lt;span class="nf"&gt;reservarEstoque&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PedidoRequest&lt;/span&gt; &lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;inventoryClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reservar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getItens&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Fallback: aceita o pedido e reconcilia o estoque de forma assíncrona&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ReservaResponse&lt;/span&gt; &lt;span class="nf"&gt;reservaOtimista&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PedidoRequest&lt;/span&gt; &lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;warn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fallback de estoque acionado para pedido {}: {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
             &lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;eventPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ReservaPendenteEvent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ReservaResponse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pendente&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No papel, tudo parecia sólido: o circuit breaker abriria, o fallback assumiria e o cliente nem perceberia.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.4 Definindo o Blast Radius
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;blast radius&lt;/strong&gt; é a área máxima de impacto que aceitamos causar. Para essa carta, ele foi limitado em quatro dimensões:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tráfego:&lt;/strong&gt; apenas os pods do &lt;code&gt;inventory-service&lt;/code&gt; marcados com &lt;code&gt;canary=chaos&lt;/code&gt;, que recebem &lt;strong&gt;10% das requisições&lt;/strong&gt; via divisão de tráfego.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geografia:&lt;/strong&gt; somente a região &lt;code&gt;sa-east-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tempo:&lt;/strong&gt; janela máxima de &lt;strong&gt;10 minutos&lt;/strong&gt;, às 14h de uma terça-feira (horário de pico moderado, time completo disponível).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependências:&lt;/strong&gt; &lt;code&gt;payment-service&lt;/code&gt; e &lt;code&gt;user-service&lt;/code&gt; ficaram explicitamente fora do escopo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Na prática, o impacto máximo teórico seria uma degradação em ~10% dos checkouts por 10 minutos — e as &lt;strong&gt;condições de aborto&lt;/strong&gt; garantiam que isso nunca chegaria perto de um incidente real.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.5 Injetando a falha
&lt;/h3&gt;

&lt;p&gt;Usamos o &lt;strong&gt;Chaos Mesh&lt;/strong&gt; no cluster EKS para injetar a latência de rede apenas nos pods canary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chaos-mesh.org/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NetworkChaos&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;copas-07-lesma-no-estoque&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;inventory&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;delay&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;namespaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inventory"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;labelSelectors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;inventory-service&lt;/span&gt;
      &lt;span class="na"&gt;canary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chaos&lt;/span&gt;
  &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;latency&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000ms"&lt;/span&gt;
    &lt;span class="na"&gt;jitter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;200ms"&lt;/span&gt;
    &lt;span class="na"&gt;correlation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;50"&lt;/span&gt;
  &lt;span class="na"&gt;direction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;to&lt;/span&gt;
  &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10m"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Observabilidade e Resultados
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Como monitoramos o experimento
&lt;/h3&gt;

&lt;p&gt;Sem observabilidade, Chaos Engineering é só sabotagem. Nossa stack para o experimento:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus + Grafana:&lt;/strong&gt; métricas do estado estável e um painel dedicado à carta, com as condições de aborto desenhadas como linhas de limite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Micrometer + Resilience4j:&lt;/strong&gt; exposição do estado do circuit breaker (&lt;code&gt;CLOSED&lt;/code&gt;, &lt;code&gt;OPEN&lt;/code&gt;, &lt;code&gt;HALF_OPEN&lt;/code&gt;) em tempo real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenTelemetry + Jaeger:&lt;/strong&gt; tracing distribuído para seguir uma requisição de ponta a ponta e ver onde o tempo estava sendo gasto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon CloudWatch:&lt;/strong&gt; métricas do ALB e do RDS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algumas das consultas que acompanhamos ao vivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Taxa de sucesso do checkout (estado estável)
sum(rate(http_server_requests_seconds_count{service="checkout", status!~"5.."}[1m]))
/
sum(rate(http_server_requests_seconds_count{service="checkout"}[1m]))

# Latência p99 do checkout
histogram_quantile(0.99,
  sum(rate(http_server_requests_seconds_bucket{service="checkout"}[1m])) by (le))

# Estado do circuit breaker (1 = OPEN)
resilience4j_circuitbreaker_state{name="inventory", state="open"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 A linha do tempo do experimento
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tempo&lt;/th&gt;
&lt;th&gt;Evento observado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+0:00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Latência injetada. Estado estável dentro do baseline.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+0:40&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;p99 do checkout sobe de 780ms para 2,1s nos pedidos roteados para o canary.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+1:10&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Threads do Tomcat no &lt;code&gt;checkout-service&lt;/code&gt; chegam a 92% de uso. 😬&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+1:35&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Taxa de sucesso cai para 97,8% — perto da condição de aborto (97%).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+1:50&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Circuit breaker finalmente abre. Fallback de reserva otimista assume.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+2:30&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Taxa de sucesso volta a 99,6%. p99 estabiliza em 310ms. ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+10:00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Experimento encerrado automaticamente. Circuit breaker volta a &lt;code&gt;CLOSED&lt;/code&gt; após o &lt;code&gt;HALF_OPEN&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  4.3 A arquitetura sobreviveu?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Sim — mas não pelo motivo que imaginávamos.&lt;/strong&gt; A hipótese foi &lt;strong&gt;parcialmente refutada&lt;/strong&gt;: o sistema se recuperou, mas levou quase &lt;strong&gt;dois minutos&lt;/strong&gt; para isso, e chegou perigosamente perto da condição de aborto.&lt;/p&gt;

&lt;p&gt;O tracing no Jaeger revelou o culpado: &lt;strong&gt;a combinação de Retry com TimeLimiter.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Uma única requisição de checkout, antes da correção:

checkout ──▶ inventory  [tentativa 1]  1500ms ⏱ timeout
         ──▶ inventory  [tentativa 2]  1500ms ⏱ timeout   (+200ms de espera)
         ──▶ inventory  [tentativa 3]  1500ms ⏱ timeout   (+200ms de espera)
         ──▶ fallback
         Total: ~4,9s segurando uma thread
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada requisição ficava quase 5 segundos presa antes de chegar ao fallback. Além disso, como o &lt;code&gt;@Retry&lt;/code&gt; estava posicionado &lt;strong&gt;fora&lt;/strong&gt; do circuit breaker na ordem de decoradores, cada tentativa era contada como uma chamada separada — mas lentas o suficiente para que a janela deslizante de 50 chamadas demorasse a encher. Resultado: &lt;strong&gt;o mecanismo que deveria proteger o sistema estava amplificando a carga&lt;/strong&gt; sobre um serviço já degradado — um clássico &lt;em&gt;retry storm&lt;/em&gt; em miniatura.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.4 Padrões de resiliência: o que funcionou e o que corrigimos
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;✅ Funcionou como esperado:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Circuit Breaker:&lt;/strong&gt; uma vez aberto, isolou completamente o serviço lento e permitiu a recuperação em segundos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fallback com reserva otimista:&lt;/strong&gt; nenhum pedido foi perdido; as reservas pendentes foram reconciliadas pelo consumidor de eventos assim que o estoque voltou.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulkhead implícito via canary:&lt;/strong&gt; os 90% de tráfego fora do canary nunca perceberam o experimento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Horizontal Pod Autoscaler:&lt;/strong&gt; escalou o &lt;code&gt;checkout-service&lt;/code&gt; de 6 para 9 réplicas ao detectar a alta de CPU, aliviando a pressão sobre as threads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🔧 O que mudamos depois do experimento:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Redução do timeout&lt;/strong&gt; de 1500ms para 800ms, alinhado ao p99.9 real do serviço de estoque.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retry com backoff exponencial e jitter&lt;/strong&gt;, limitado a 2 tentativas, e apenas para erros transitórios (não para timeouts).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ajuste da ordem dos decoradores&lt;/strong&gt; para que o circuit breaker avalie o resultado agregado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulkhead explícito&lt;/strong&gt; (pool de threads dedicado) para a chamada ao estoque, impedindo que ela consuma todas as threads do Tomcat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Novo alerta&lt;/strong&gt; para uso de threads acima de 80%.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4.5 Reexecutando a carta
&lt;/h3&gt;

&lt;p&gt;Duas semanas depois, rodamos a mesma carta novamente. O resultado:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Métrica&lt;/th&gt;
&lt;th&gt;1ª execução&lt;/th&gt;
&lt;th&gt;2ª execução&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tempo até o circuit breaker abrir&lt;/td&gt;
&lt;td&gt;1min50s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;14s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Menor taxa de sucesso observada&lt;/td&gt;
&lt;td&gt;97,8%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;99,4%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pico de p99 do checkout&lt;/td&gt;
&lt;td&gt;4,9s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;920ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pico de uso de threads&lt;/td&gt;
&lt;td&gt;92%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;41%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hipótese&lt;/td&gt;
&lt;td&gt;Parcialmente refutada&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Confirmada&lt;/strong&gt; ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Essa é a beleza do Master Deck: &lt;strong&gt;a carta não é descartada depois de jogada.&lt;/strong&gt; Ela volta para o baralho e é incorporada ao nosso pipeline de CI/CD, rodando automaticamente em staging a cada release do &lt;code&gt;checkout-service&lt;/code&gt;. Se alguém reintroduzir o problema, descobrimos antes da produção.&lt;/p&gt;




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

&lt;p&gt;Quebrar coisas de propósito pode parecer contraintuitivo, mas o experimento da carta &lt;strong&gt;♥️ Copas 7&lt;/strong&gt; mostrou exatamente por que fazemos isso: &lt;strong&gt;nossa configuração de resiliência estava errada, e nenhum teste convencional teria revelado.&lt;/strong&gt; Ela passava em todos os testes unitários e de integração. Só falhou sob as condições reais de um sistema distribuído em produção.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lições aprendidas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Padrões de resiliência mal configurados podem ser piores do que nenhum.&lt;/strong&gt; Retry sem limites e timeouts generosos transformam uma falha pequena em uma falha em cascata.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latência é mais perigosa que indisponibilidade.&lt;/strong&gt; Um serviço lento consome recursos de todos que dependem dele.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O estado estável deve ser medido pelo negócio.&lt;/strong&gt; Foi a taxa de sucesso do checkout — e não a CPU — que nos mostrou o problema real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blast radius pequeno permite aprender com segurança.&lt;/strong&gt; Com 10% do tráfego e condições de aborto claras, descobrimos uma fraqueza séria sem gerar um único incidente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observabilidade é pré-requisito.&lt;/strong&gt; Sem tracing distribuído, teríamos visto apenas "o checkout ficou lento" — e não o &lt;em&gt;porquê&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  O impacto na cultura DevOps
&lt;/h3&gt;

&lt;p&gt;O maior ganho do ChaosEngineeringMasterDeck não foi técnico, foi &lt;strong&gt;cultural&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resiliência virou responsabilidade de todos&lt;/strong&gt;, não só do time de SRE. Desenvolvedores de produto agora criam suas próprias cartas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Os Game Days viraram rituais esperados&lt;/strong&gt; — a gamificação reduziu o medo de "mexer em produção" e aumentou o engajamento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Os postmortems ganharam continuidade:&lt;/strong&gt; todo incidente real gera uma nova carta, garantindo que a mesma falha seja testada para sempre.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A confiança mudou de natureza:&lt;/strong&gt; antes, &lt;em&gt;achávamos&lt;/em&gt; que o sistema aguentaria. Agora, &lt;em&gt;temos evidência&lt;/em&gt; de que aguenta — e sabemos exatamente quais cartas ainda não jogamos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você quer começar, não precisa de um baralho completo. Escolha &lt;strong&gt;uma dependência crítica&lt;/strong&gt;, escreva &lt;strong&gt;uma hipótese&lt;/strong&gt;, defina &lt;strong&gt;um blast radius pequeno&lt;/strong&gt; e rode &lt;strong&gt;um experimento em staging&lt;/strong&gt;. O caos vai acontecer de qualquer forma — a única pergunta é se você vai estar preparado quando ele chegar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E você? Qual seria a primeira carta do seu baralho?&lt;/strong&gt; Conta aqui nos comentários! 👇&lt;/p&gt;




&lt;h3&gt;
  
  
  📚 Referências e leituras recomendadas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://principlesofchaos.org" rel="noopener noreferrer"&gt;Principles of Chaos Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Rosenthal, C.; Jones, N. &lt;em&gt;Chaos Engineering: System Resiliency in Practice&lt;/em&gt;. O'Reilly, 2020.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://resilience4j.readme.io" rel="noopener noreferrer"&gt;Documentação do Resilience4j&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chaos-mesh.org/docs/" rel="noopener noreferrer"&gt;Documentação do Chaos Mesh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/fis/" rel="noopener noreferrer"&gt;AWS Fault Injection Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Nygard, M. &lt;em&gt;Release It!: Design and Deploy Production-Ready Software&lt;/em&gt;. 2ª ed. Pragmatic Bookshelf, 2018.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>chaosengineering</category>
      <category>sre</category>
      <category>devops</category>
      <category>aws</category>
    </item>
    <item>
      <title>Padrão de Projeto Decorator: Adicionando Funcionalidades sem Quebrar sua Arquitetura</title>
      <dc:creator>Gabriel Bertonsin</dc:creator>
      <pubDate>Sat, 12 Sep 2026 23:24:35 +0000</pubDate>
      <link>https://dev.to/gabriel_berton_brito/padrao-de-projeto-decorator-adicionando-funcionalidades-sem-quebrar-sua-arquitetura-c0h</link>
      <guid>https://dev.to/gabriel_berton_brito/padrao-de-projeto-decorator-adicionando-funcionalidades-sem-quebrar-sua-arquitetura-c0h</guid>
      <description>&lt;p&gt;Se você já trabalhou com orientação a objetos por algum tempo, provavelmente já se deparou com este dilema: &lt;strong&gt;como adicionar novas funcionalidades a um objeto sem criar uma explosão de subclasses?&lt;/strong&gt; Imagine um sistema de componentes gráficos onde você precisa combinar bordas, sombras, cores e efeitos de diferentes formas. Criar uma subclasse para cada combinação possível rapidamente se torna insustentável.&lt;/p&gt;

&lt;p&gt;É exatamente para resolver esse tipo de problema que existe o &lt;strong&gt;Decorator&lt;/strong&gt;, um dos padrões de projeto estruturais mais elegantes do catálogo GoF (Gang of Four).&lt;/p&gt;

&lt;p&gt;Neste artigo, vou explicar o que é o padrão Decorator, quando ele deve ser usado e como implementá-lo na prática com um exemplo completo em Java.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é o padrão Decorator?
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;Decorator&lt;/strong&gt; é um padrão de design estrutural que permite &lt;strong&gt;adicionar comportamento a objetos individuais de forma dinâmica e transparente&lt;/strong&gt;, sem afetar outros objetos da mesma classe.&lt;/p&gt;

&lt;p&gt;Em vez de estender uma classe para adicionar uma nova responsabilidade (o que gera herança rígida e múltiplas subclasses), o Decorator &lt;strong&gt;envolve&lt;/strong&gt; o objeto original com uma camada adicional de comportamento — como se fosse uma "embalagem" que soma funcionalidades sem alterar a estrutura interna do objeto decorado.&lt;/p&gt;

&lt;p&gt;O resultado é um sistema muito mais &lt;strong&gt;flexível e modular&lt;/strong&gt;, no qual novas combinações de comportamento podem ser criadas em tempo de execução, simplesmente combinando decoradores diferentes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vantagens do Decorator
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexibilidade e modularidade&lt;/strong&gt;: permite estender o comportamento de objetos individuais sem afetar os demais.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evita a explosão de subclasses&lt;/strong&gt;: ao invés de criar uma classe para cada combinação de funcionalidades, você combina decoradores.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsabilidade única&lt;/strong&gt;: cada decorador cuida de uma única responsabilidade, mantendo o código mais limpo e coeso.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quando usar o Decorator?
&lt;/h2&gt;

&lt;p&gt;Esse padrão é especialmente útil quando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você precisa &lt;strong&gt;adicionar responsabilidades a objetos dinamicamente&lt;/strong&gt;, sem modificar seu código-fonte.&lt;/li&gt;
&lt;li&gt;Você quer &lt;strong&gt;evitar a criação de subclasses excessivas&lt;/strong&gt; para representar cada combinação possível de comportamentos.&lt;/li&gt;
&lt;li&gt;Você busca uma &lt;strong&gt;alternativa à herança&lt;/strong&gt; para estender funcionalidades de forma mais flexível.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Estrutura do Padrão
&lt;/h2&gt;

&lt;p&gt;O Decorator é composto por quatro elementos principais:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Componente (Component)
&lt;/h3&gt;

&lt;p&gt;Define a interface comum para os objetos que podem receber responsabilidades adicionais. É o contrato que tanto os componentes concretos quanto os decoradores devem seguir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Componente&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Componente Concreto (Concrete Component)
&lt;/h3&gt;

&lt;p&gt;Implementa o comportamento básico do componente — é o objeto "puro", sem nenhuma decoração aplicada ainda.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Componente Concreto&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Drawing a button"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Decorador (Decorator)
&lt;/h3&gt;

&lt;p&gt;Essa é a peça central do padrão. O decorador:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mantém uma &lt;strong&gt;referência&lt;/strong&gt; para um objeto do tipo &lt;code&gt;Component&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implementa a mesma interface&lt;/strong&gt; do componente base, garantindo que possa ser usado no lugar dele.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encapsula&lt;/strong&gt; o componente original e adiciona um comportamento extra.&lt;/li&gt;
&lt;li&gt;Pode ser estendido por subclasses para implementar responsabilidades específicas.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Decorador&lt;/span&gt;
&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BorderDecorator&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BorderDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;draw&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;drawBorder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;drawBorder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que o método &lt;code&gt;draw()&lt;/code&gt; primeiro chama o comportamento original (&lt;code&gt;component.draw()&lt;/code&gt;) e &lt;strong&gt;depois&lt;/strong&gt; adiciona o novo comportamento (&lt;code&gt;drawBorder()&lt;/code&gt;). Essa é a essência do padrão: compor comportamentos em camadas.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Decorador Concreto (Concrete Decorator)
&lt;/h3&gt;

&lt;p&gt;Estende o decorador abstrato e implementa a funcionalidade específica que será adicionada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Decorador Concreto&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RedBorderDecorator&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BorderDecorator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;RedBorderDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;drawBorder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Drawing a red border"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Colocando tudo em prática
&lt;/h2&gt;

&lt;p&gt;Com as classes definidas, podemos ver o padrão em ação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Componente original&lt;/span&gt;
        &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Decorando o componente original com uma borda vermelha&lt;/span&gt;
        &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="n"&gt;decoratedButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RedBorderDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Desenhando o componente decorado&lt;/span&gt;
        &lt;span class="n"&gt;decoratedButton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;draw&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Saída esperada:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Drawing a button
Drawing a red border
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que o botão original &lt;strong&gt;não foi alterado&lt;/strong&gt;. Ele continua existindo como uma implementação independente. A borda vermelha foi adicionada &lt;strong&gt;dinamicamente&lt;/strong&gt;, "envolvendo" o botão em uma nova camada de comportamento. Se amanhã precisarmos de um botão com borda azul, ou com borda e sombra combinadas, basta criar (ou combinar) novos decoradores — sem tocar na classe &lt;code&gt;Button&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Por que isso importa?
&lt;/h2&gt;

&lt;p&gt;O grande ganho do Decorator está em &lt;strong&gt;respeitar o princípio Aberto/Fechado&lt;/strong&gt; (Open/Closed Principle): as classes ficam abertas para extensão, mas fechadas para modificação. Isso significa que podemos adicionar novos comportamentos ao sistema sem correr o risco de quebrar código já existente e testado.&lt;/p&gt;

&lt;p&gt;Além disso, como os decoradores podem ser &lt;strong&gt;empilhados&lt;/strong&gt; (um decorador pode envolver outro decorador), é possível construir combinações complexas de comportamento a partir de peças simples e reutilizáveis — algo muito mais elegante do que uma árvore de herança cheia de subclasses.&lt;/p&gt;




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

&lt;p&gt;O padrão Decorator é uma ferramenta poderosa para quem busca &lt;strong&gt;flexibilidade&lt;/strong&gt; no design de sistemas orientados a objetos. Ao substituir a herança rígida por composição dinâmica, ele permite adicionar responsabilidades a objetos de forma modular, reutilizável e sem efeitos colaterais sobre outras instâncias da mesma classe.&lt;/p&gt;

&lt;p&gt;Esse padrão é amplamente utilizado em bibliotecas e frameworks conhecidos — por exemplo, o próprio &lt;code&gt;java.io&lt;/code&gt; do Java (como &lt;code&gt;BufferedReader&lt;/code&gt; envolvendo um &lt;code&gt;FileReader&lt;/code&gt;) é um exemplo clássico de Decorator aplicado na prática.&lt;/p&gt;

&lt;p&gt;Entender e saber aplicar o Decorator é um passo importante para escrever código mais limpo, extensível e alinhado com boas práticas de design orientado a objetos.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>java</category>
      <category>softwaredevelopment</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
