<?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: Gustavo B. de Abreu</title>
    <description>The latest articles on DEV Community by Gustavo B. de Abreu (@eugustavoabreu).</description>
    <link>https://dev.to/eugustavoabreu</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%2F4101509%2F67f2cb7f-7077-4556-9052-9d449cc3c841.jpg</url>
      <title>DEV Community: Gustavo B. de Abreu</title>
      <link>https://dev.to/eugustavoabreu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eugustavoabreu"/>
    <language>en</language>
    <item>
      <title>Sobrevivendo ao Inevitável: Engenharia do Caos na Prática com o ChaosEngineeringMasterDeck</title>
      <dc:creator>Gustavo B. de Abreu</dc:creator>
      <pubDate>Sun, 11 Oct 2026 02:18:55 +0000</pubDate>
      <link>https://dev.to/eugustavoabreu/sobrevivendo-ao-inevitavel-engenharia-do-caos-na-pratica-com-o-chaosengineeringmasterdeck-3dni</link>
      <guid>https://dev.to/eugustavoabreu/sobrevivendo-ao-inevitavel-engenharia-do-caos-na-pratica-com-o-chaosengineeringmasterdeck-3dni</guid>
      <description>&lt;p&gt;Se você trabalha com arquiteturas modernas em nuvem e microsserviços, provavelmente já se deparou com a clássica citação de Werner Vogels, CTO da Amazon:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Failures are a given and everything will eventually fail over time."&lt;/em&gt; (Falhas são inevitáveis e tudo falhará com o tempo).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Em sistemas distribuídos, isso não é apenas uma frase de efeito; é uma realidade técnica. Redes sofrem partições, zonas de disponibilidade passam por degradação, storages saturam, &lt;em&gt;garbage collectors&lt;/em&gt; pausam execuções e bancos de dados encontram contenções de lock. Conforme os serviços se multiplicam em topologias complexas, o comportamento emergente dessas interações torna-se não linear e altamente imprevisível.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn0leb761mvlo44i46ut2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn0leb761mvlo44i46ut2.jpeg" alt="DIAGRAMA 1: Topologia de Microsserviços e Efeito Dominó em Sistemas Distribuídos" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  O Limite dos Testes Tradicionais
&lt;/h3&gt;

&lt;p&gt;Historicamente, a engenharia de software concentrou seus esforços de qualidade em testes unitários, testes de integração e testes ponta a ponta. Embora indispensáveis, &lt;strong&gt;os testes tradicionais validam exclusivamente condições conhecidas&lt;/strong&gt; — a essência da premissa &lt;code&gt;assert(A == B)&lt;/code&gt; executada em um ambiente isolado e previsível.&lt;/p&gt;

&lt;p&gt;O perigo em produção mora no &lt;strong&gt;desconhecido&lt;/strong&gt;: o que acontece quando uma API externa não cai de vez (retornando um HTTP 500 rápido), mas começa a responder com latência intermitente de 900 ms e perda pontual de pacotes? Na ausência de isolamento, isso gera &lt;strong&gt;esgotamento de pools de threads&lt;/strong&gt;, tempestades de retentativas (&lt;em&gt;retry storms&lt;/em&gt;) e indisponibilidade generalizada.&lt;/p&gt;

&lt;p&gt;É nesse cenário que a &lt;strong&gt;Engenharia do Caos (Chaos Engineering)&lt;/strong&gt; atua:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Chaos Engineering é a disciplina de experimentar sobre um sistema a fim de construir confiança em sua capacidade de resistir a condições turbulentas em produção."&lt;/em&gt; — &lt;em&gt;Principles of Chaos Engineering&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como sintetizou Nora Jones: &lt;em&gt;"O caos não causa problemas. Ele os revela."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Mudar a mentalidade da equipe significa abandonar a busca utópica por sistemas invulneráveis e adotar a prática de projetar para &lt;strong&gt;degradação graciosa&lt;/strong&gt;, failover testado e contenção ativa.&lt;/p&gt;




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

&lt;p&gt;O &lt;strong&gt;ChaosEngineeringMasterDeck&lt;/strong&gt; consolida os aprendizados desenvolvidos nos GameDays da Amazon e na experiência de resiliência da AWS e Netflix. No fluxo de trabalho do nosso projeto, o Master Deck atua como um catálogo operacional e framework para conduzir testes baseados no &lt;strong&gt;método científico&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdlu6zk8z3szyaun73fas.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdlu6zk8z3szyaun73fas.jpeg" alt="DIAGRAMA 2: O Loop Científico do Caos - Steady State, Hipótese, Experimento, Verificação e Melhoria" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  As 5 Fases de Cada Experimento
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Estado Estável (&lt;em&gt;Steady State&lt;/em&gt;):&lt;/strong&gt; Definição do comportamento nominal do sistema orientada a &lt;strong&gt;métricas de negócio e experiência do usuário&lt;/strong&gt;. O Master Deck reforça que métricas puramente computacionais (como CPU a 60%) não garantem que o usuário está sendo atendido. Mede-se o estado estável por indicadores como &lt;em&gt;taxa de checkout por segundo&lt;/em&gt; (similar ao SPS da Netflix) ou latência percebida na borda.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hipótese (&lt;em&gt;Hypothesis&lt;/em&gt;):&lt;/strong&gt; Formulação técnica estruturada no formato &lt;em&gt;"E se...?"&lt;/em&gt; (&lt;em&gt;What if...?&lt;/em&gt;). Por exemplo: &lt;em&gt;"Se o gateway de pagamentos atrasar 800 ms, o Circuit Breaker abrirá e as requisições serão degradadas graciosamente sem travar o pool de conexões"&lt;/em&gt;.
&lt;em&gt;Princípio-chave:&lt;/em&gt; &lt;strong&gt;"Never assume. If you haven't verified it, it's probably broken."&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execução (&lt;em&gt;Run Experiment&lt;/em&gt;):&lt;/strong&gt; Injeção da falha com escopo delimitado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verificação (&lt;em&gt;Verify&lt;/em&gt;):&lt;/strong&gt; Avaliação precisa do impacto e dos tempos operacionais:

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Time to Detect (Tempo de detecção)&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Time to Graceful Degradation (Tempo de acionamento do fallback)&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;MTTR (Mean Time to Repair)&lt;/em&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A disponibilidade de qualquer serviço é governada pela relação:&lt;br&gt;&lt;br&gt;
   &lt;strong&gt;Disponibilidade = MTBF / (MTBF + MTTR)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
   Como falhas sempre ocorrerão em algum momento (desafiando o MTBF), a automação e o teste contínuo reduzem o MTTR para proteger o SLA.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Melhoria (&lt;em&gt;Improve&lt;/em&gt;):&lt;/strong&gt; Condução de análise pós-incidente (&lt;em&gt;Correction of Errors - COE&lt;/em&gt;) e implementação das correções de arquitetura.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Controles Críticos de Segurança
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blast Radius (Raio de Explosão) Controlado:&lt;/strong&gt; Os testes começam na menor granularidade possível (instância única, tráfego canário ou staging espelhado) antes de expandir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Emergency Stop (Botão de Aborto Imediato):&lt;/strong&gt; Se as métricas vitais de negócio ultrapassarem o limiar tolerado de segurança, o experimento é interrompido instantaneamente.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Estudo de Caso Prático: Simulando Falha em Microsserviços
&lt;/h2&gt;

&lt;p&gt;Para tangibilizar o processo, aplicamos as diretrizes do Master Deck a uma arquitetura distribuída de e-commerce e processamento de pedidos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5ruaqgfz8s89369ncunv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5ruaqgfz8s89369ncunv.jpeg" alt="DIAGRAMA 3: Topologia da Arquitetura do Fluxo de Pedidos e Ponto de Injeção de Falha" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A "Carta" de Caos Selecionada
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identificador da Instrução:&lt;/strong&gt; &lt;code&gt;DECK-NET-03: Latency &amp;amp; Packet Loss in Downstream Dependency&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alvo:&lt;/strong&gt; Rota de comunicação entre o microsserviço de pedidos (&lt;em&gt;Order Service&lt;/em&gt;) e o proxy de integração com o gateway de pagamento externo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mecanismo de Injeção:&lt;/strong&gt; Configuração do &lt;strong&gt;ToxiProxy&lt;/strong&gt; para introduzir uma latência de &lt;strong&gt;850 ms (com jitter de ±150 ms)&lt;/strong&gt; e uma taxa de perda de pacotes de &lt;strong&gt;5%&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Injetando latência e perda de pacotes via ToxiProxy CLI&lt;/span&gt;
toxiproxy-cli toxic add payment_service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--type&lt;/span&gt; latency &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--attribute&lt;/span&gt; &lt;span class="nv"&gt;latency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;850 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--attribute&lt;/span&gt; &lt;span class="nv"&gt;jitter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;150

toxiproxy-cli toxic add payment_service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--type&lt;/span&gt; loss &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--attribute&lt;/span&gt; &lt;span class="nv"&gt;percent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hipótese do Experimento
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Sob latência média de 850 ms e perda de pacotes de 5% no gateway de pagamento, o Circuit Breaker configurado no Order Service deverá transicionar para o estado OPEN em menos de 5 segundos. Com isso, o fallback será disparado, enviando os pedidos para liquidação assíncrona com confirmação provisória, preservando a taxa de sucesso da rota acima de 99% e impedindo o esgotamento do pool de threads do Tomcat."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Delimitação do Blast Radius
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ambiente:&lt;/strong&gt; Ambiente de staging espelhado com carga sintética de 350 requisições/s gerada via ferramenta de benchmarking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gatilho de Aborto (Emergency Stop):&lt;/strong&gt; Se a taxa de respostas HTTP 500 subir acima de 2% no API Gateway ou a latência p99 exceder 1.500 ms, a injeção é cessada imediatamente.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq02g8ppu2f4swoi5xbym.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq02g8ppu2f4swoi5xbym.jpeg" alt="DIAGRAMA 4: Transição de Estados do Circuit Breaker (Closed, Open e Half-Open)" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cronologia da Execução
&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;Comportamento Registrado na Telemetria&lt;/th&gt;
&lt;th&gt;Ação dos Padrões de Resiliência&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+00:00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Estado estável: 350 req/s, latência p95 de 42 ms, taxa de erro de 0%.&lt;/td&gt;
&lt;td&gt;Sistema operando dentro dos parâmetros nominais.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+01:00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ativação dos tóxicos de latência e perda de pacotes no ToxiProxy.&lt;/td&gt;
&lt;td&gt;Elevação pontual na fila de conexões pendentes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+01:04&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A taxa de chamadas lentas excede o limiar de 50% na janela deslizante.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Circuit Breaker transiciona para OPEN&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+01:05&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Chamadas síncronas bloqueadas localmente via &lt;em&gt;fast-fail&lt;/em&gt;.&lt;/td&gt;
&lt;td&gt;O método de &lt;strong&gt;Fallback&lt;/strong&gt; entra em ação: registra o pedido em status pendente e repassa a liquidação para processamento assíncrono em fila.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+01:06 - T+08:00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Carga de 350 req/s mantida sob falha da dependência.&lt;/td&gt;
&lt;td&gt;Latência p95 cai para 38 ms graças ao retorno imediato do fallback; zero esgotamento de threads.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;T+08:00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Remoção do tóxico no ToxiProxy.&lt;/td&gt;
&lt;td&gt;O circuito transiciona para &lt;strong&gt;HALF-OPEN&lt;/strong&gt;, valida as chamadas de teste e retorna ao estado &lt;strong&gt;CLOSED&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Configuração de Resiliência Aplicada
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resilience4j.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;paymentService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;slidingWindowType&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;slidingWindowSize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
      &lt;span class="na"&gt;minimumNumberOfCalls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
      &lt;span class="na"&gt;failureRateThreshold&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;slowCallRateThreshold&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;slowCallDurationThreshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;500ms&lt;/span&gt;
      &lt;span class="na"&gt;waitDurationInOpenState&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10000ms&lt;/span&gt;
      &lt;span class="na"&gt;permittedNumberOfCallsInHalfOpenState&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;automaticTransitionFromOpenToHalfOpenEnabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;resilience4j.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;paymentService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;timeoutDuration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;600ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementação do Padrão com Fallback Gracioso
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderCheckoutService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PaymentClient&lt;/span&gt; &lt;span class="n"&gt;paymentClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PendingPaymentQueue&lt;/span&gt; &lt;span class="n"&gt;pendingPaymentQueue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&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;"paymentService"&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;"processPaymentFallback"&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;CheckoutResponse&lt;/span&gt; &lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;PaymentResult&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paymentClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authorize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPaymentDetails&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;CheckoutResponse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;approved&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOrderId&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTransactionId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;CheckoutResponse&lt;/span&gt; &lt;span class="nf"&gt;processPaymentFallback&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderRequest&lt;/span&gt; &lt;span class="n"&gt;request&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;"Serviço de pagamento indisponível ou instável. Acionando fallback assíncrono."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pendingPaymentQueue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enqueueForAsyncProcessing&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&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;CheckoutResponse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;acceptedAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOrderId&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; 
            &lt;span class="s"&gt;"Seu pedido foi recebido e está sendo liquidado em segundo plano."&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;
  
  
  Padrões Arquiteturais Validados
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Circuit Breaker com Fast-Fail:&lt;/strong&gt; Interrompeu a espera de rede, evitando bloqueio generalizado e exaustão do pool de threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulkhead (Isolamento de Recursos):&lt;/strong&gt; A saturação da integração de pagamentos não comprometeu o catálogo de produtos ou endpoints de autenticação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retry com Backoff Exponencial e Jitter:&lt;/strong&gt; Garantiu que o reprocessamento da fila de contingência não gerasse um pico repentino de carga (&lt;em&gt;thundering herd&lt;/em&gt;) quando o gateway se recuperou.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-Healing e Multi-AZ:&lt;/strong&gt; Em testes adicionais de derrubada de nós, o pool de instâncias restabeleceu conexões com a réplica sem indisponibilidade de transações.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Conclusão e Lições de Cultura
&lt;/h2&gt;

&lt;p&gt;A execução periódica de experimentos guiados pelo &lt;strong&gt;ChaosEngineeringMasterDeck&lt;/strong&gt; transforma a postura operacional da organização.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principais Lições Aprendidas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Suposições teóricas não substituem validação prática:&lt;/strong&gt; Antes do teste, acreditava-se que os timeouts de rede padrão protegeriam a aplicação, quando na prática teriam derrubado o pool de conexões em poucos segundos sob carga moderada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cultura Blameless (Sem Culpa):&lt;/strong&gt; Incidentes identificados durante os testes servem para aprimorar o sistema. Seguindo o modelo de &lt;strong&gt;Correction of Errors (COE)&lt;/strong&gt;, a equipe investiga causas sistêmicas por meio dos &lt;em&gt;5 Porquês&lt;/em&gt;, eliminando pontos únicos de falha de forma contínua.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treinamento e Prontidão de Resposta:&lt;/strong&gt; Conduzir simulações combate a atrofia de habilidades das equipes de engenharia e operações. Como bem pontuou Jesse Robbins, criador dos GameDays na Amazon:
&amp;gt; &lt;em&gt;"You don't choose the moment, the moment chooses you. You only choose how prepared you are when it does."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Engenharia do Caos não é quebrar coisas sem controle; é um método estruturado para assegurar previsibilidade e confiança na infraestrutura.&lt;/p&gt;

&lt;p&gt;Nas palavras finais de Adrian Hornsby no Master Deck:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Chaos Engineering won't make your system more robust, People will."&lt;/strong&gt; (A Engenharia do Caos não tornará seu sistema mais robusto; as pessoas farão isso).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Referências e Leituras Recomendadas
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Principles of Chaos Engineering&lt;/strong&gt; (principlesofchaos.org).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chaos Engineering on AWS: Building Resilient Systems&lt;/strong&gt; — Adrian Hornsby.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ByteByteGo: System Design Interview &amp;amp; Resilient Patterns&lt;/strong&gt; — Alex Xu.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release It!: Design and Deploy Production-Ready Software&lt;/strong&gt; — Michael T. Nygard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Amazon Builders' Library: Challenges with Distributed Systems&lt;/strong&gt; — AWS.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>chaosengineering</category>
      <category>devops</category>
      <category>aws</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Mastering the Adapter Pattern in Java: Bridging Modern Architectures and Legacy Systems</title>
      <dc:creator>Gustavo B. de Abreu</dc:creator>
      <pubDate>Sun, 30 Aug 2026 20:52:01 +0000</pubDate>
      <link>https://dev.to/eugustavoabreu/mastering-the-adapter-pattern-in-java-bridging-modern-architectures-and-legacy-systems-78j</link>
      <guid>https://dev.to/eugustavoabreu/mastering-the-adapter-pattern-in-java-bridging-modern-architectures-and-legacy-systems-78j</guid>
      <description>&lt;h2&gt;
  
  
  1. Fundamental Base: The Problem and the Theory
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 Introduction
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Adapter Pattern&lt;/strong&gt; (also widely known by its alias, &lt;strong&gt;Wrapper&lt;/strong&gt;) belongs to the &lt;strong&gt;Structural Design Patterns&lt;/strong&gt; category. Structural patterns deal with object composition, establishing clean relationships and interfaces across disparate classes to form larger, flexible structures without introducing tight coupling.&lt;/p&gt;

&lt;p&gt;According to the canonical definition by the Gang of Four (GoF):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces."&lt;/em&gt; (Gamma et al., 1994).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In enterprise Java ecosystems, the Adapter pattern serves as an indispensable architectural bridge whenever we need to integrate legacy components, proprietary third-party SDKs, or external services whose contracts diverge from our core domain model.&lt;/p&gt;




&lt;h3&gt;
  
  
  1.2 The Problem: Architectural Friction with Incompatible Interfaces
&lt;/h3&gt;

&lt;p&gt;In day-to-day software engineering, teams frequently encounter highly stable, battle-tested utilities, mainframe integrations, or third-party libraries whose public interfaces &lt;strong&gt;do not match the domain interface&lt;/strong&gt; required by the consuming system.&lt;/p&gt;

&lt;p&gt;When this structural friction occurs, developers often face three problematic alternatives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Modifying the existing class/service (&lt;code&gt;Adaptee&lt;/code&gt;):&lt;/strong&gt; Often impossible when consuming compiled third-party JARs or closed-source code. Even if the source code is available, forcing low-level infrastructure or external utilities to adopt domain-specific contracts violates the Single Responsibility Principle (SRP).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Polluting the client code:&lt;/strong&gt; Littering domain services with primitive type conversions, legacy status parsing, and foreign dependencies introduces tight coupling and tech debt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rewriting the component from scratch:&lt;/strong&gt; Incurs massive engineering costs, delivery delays, and high regression risks in critical, already-validated business logic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The core problem the Adapter pattern solves is: &lt;strong&gt;how can we enable collaboration between decoupled, unrelated classes without altering either the client's expected interface or the existing component's implementation&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  1.3 The Concept: How the Pattern Works
&lt;/h3&gt;

&lt;h4&gt;
  
  
  The Physical Analogy
&lt;/h4&gt;

&lt;p&gt;Consider international travel: you bring a laptop with a standard Brazilian/European three-pin power plug and need to plug it into a US wall socket (two flat pins).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You cannot break the hotel wall to replace the electrical outlet (&lt;code&gt;Adaptee&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;You do not cut off your laptop charger’s cord (&lt;code&gt;Client&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;You simply plug your charger into a &lt;strong&gt;travel power adapter (&lt;code&gt;Adapter&lt;/code&gt;)&lt;/strong&gt;, which accepts your laptop plug on one side and fits into the wall socket on the other, translating the physical interface transparently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Structural Breakdown
&lt;/h4&gt;

&lt;p&gt;The pattern defines four core participants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Target:&lt;/strong&gt; Defines the domain-specific interface that the &lt;code&gt;Client&lt;/code&gt; expects and uses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client:&lt;/strong&gt; Collaborates with objects conforming to the &lt;code&gt;Target&lt;/code&gt; interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptee:&lt;/strong&gt; Defines the existing, incompatible interface that requires adaptation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adapter:&lt;/strong&gt; Implements the &lt;code&gt;Target&lt;/code&gt; interface and delegates requests internally to the &lt;code&gt;Adaptee&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Object Adapter vs. Class Adapter
&lt;/h4&gt;

&lt;p&gt;The GoF specification outlines two distinct implementation strategies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Object Adapter (Composition-based):&lt;/strong&gt; The &lt;code&gt;Adapter&lt;/code&gt; implements the &lt;code&gt;Target&lt;/code&gt; interface and holds an internal reference (composition) to the &lt;code&gt;Adaptee&lt;/code&gt; instance. When a target method is called, it translates parameters and invokes the corresponding method on the adaptee. &lt;strong&gt;This is the standard, idiomatic approach in Java&lt;/strong&gt;, adhering to the principle of &lt;em&gt;favoring object composition over class inheritance&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Class Adapter (Multiple Inheritance-based):&lt;/strong&gt; The &lt;code&gt;Adapter&lt;/code&gt; inherits simultaneously from both &lt;code&gt;Target&lt;/code&gt; and &lt;code&gt;Adaptee&lt;/code&gt;. In Java (which does not support multiple inheritance of concrete classes), this variant is only possible when &lt;code&gt;Target&lt;/code&gt; is a pure &lt;code&gt;interface&lt;/code&gt; and &lt;code&gt;Adaptee&lt;/code&gt; is inherited via &lt;code&gt;extends&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  2. Development: Case Study, Architecture, and Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Real-World Scenario: Modern Payment Gateway vs. Legacy Core Banking
&lt;/h3&gt;

&lt;p&gt;Consider a typical high-throughput engineering scenario: an e-commerce platform transitioning towards a modern microservices architecture. The checkout domain enforces a standardized contract (&lt;code&gt;ProcessadorPagamento&lt;/code&gt;) using expressive, immutable domain models, &lt;code&gt;BigDecimal&lt;/code&gt; precision, &lt;code&gt;UUID&lt;/code&gt; transaction tracking, and explicit result objects.&lt;/p&gt;

&lt;p&gt;However, settlement operations must integrate directly with an on-premises &lt;strong&gt;Legacy Banking System&lt;/strong&gt; (&lt;code&gt;LegacyBankService&lt;/code&gt;). This legacy service is provided via a proprietary binary client and presents several constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It rejects modern domain models and exclusively accepts primitive data types (e.g., transaction amounts formatted as integer cents using &lt;code&gt;long&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;It returns raw numeric status codes (where &lt;code&gt;200&lt;/code&gt; represents success and other integers denote specific failure states) rather than rich domain objects or structured exceptions.&lt;/li&gt;
&lt;li&gt;The legacy component cannot be modified, as it is a shared dependency across multiple institutional applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without an architectural buffer, the checkout domain would become coupled to legacy data types, custom status parsing, and external SDK logic. By introducing an &lt;strong&gt;Object Adapter&lt;/strong&gt;, we establish an Anti-Corruption Layer that isolates the domain while delegating execution to the legacy core.&lt;/p&gt;




&lt;h3&gt;
  
  
  2.2 Visual Representation: Class Structure and System Architecture
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. UML Class Diagram
&lt;/h4&gt;

&lt;p&gt;The class diagram below illustrates the structural relationships between the client, the domain interface, the adapter implementation, and the legacy dependency.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi1fwa1lmfesa73bcin5u.png" alt=" " width="800" height="450"&gt;
&lt;/h2&gt;

&lt;h4&gt;
  
  
  2. High-Level Software Architecture Diagram
&lt;/h4&gt;

&lt;p&gt;The architecture diagram below highlights where the Adapter pattern sits within the end-to-end checkout pipeline, buffering domain microservices from legacy downstream infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4y68ijmdmztlpj9xt61o.png" alt=" " width="800" height="1489"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.3 Java Implementation
&lt;/h3&gt;

&lt;h3&gt;
  
  
  2.3 Java Implementation
&lt;/h3&gt;

&lt;p&gt;Below is the complete, decoupled, and production-grade implementation of the Adapter pattern in Java.&lt;/p&gt;




&lt;h4&gt;
  
  
  1. Target Interface &amp;amp; Domain Models
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;PaymentProcessor.java (Target Interface)&lt;/strong&gt;&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.target&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.domain.PaymentCharge&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.domain.PaymentResult&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * TARGET: The standard contract expected by modern internal services.
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;PaymentResult&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentCharge&lt;/span&gt; &lt;span class="n"&gt;charge&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;b&gt;Click to view Domain Models (PaymentCharge &amp;amp; PaymentResult)&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PaymentCharge.java&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.domain&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.math.BigDecimal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Objects&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Immutable Domain Model representing an incoming payment request.
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentCharge&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;transactionId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;customerEmail&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;PaymentCharge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;transactionId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;customerEmail&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compareTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ZERO&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="o"&gt;;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Payment amount must be strictly positive."&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;transactionId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requireNonNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transactionId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Transaction ID cannot be null."&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;customerEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requireNonNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customerEmail&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Customer email cannot be null."&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;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getTransactionId&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;transactionId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="nf"&gt;getAmount&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;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getCustomerEmail&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;customerEmail&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;PaymentResult.java&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.domain&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Domain-level result object returned to consuming services.
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentResult&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;successful&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&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;PaymentResult&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;successful&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&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;successful&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;successful&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&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;boolean&lt;/span&gt; &lt;span class="nf"&gt;isSuccessful&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;successful&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getMessage&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;message&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"PaymentResult{successful="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;successful&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", message='"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'}"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. The Legacy Adaptee Component
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;LegacyBankingService.java (Adaptee)&lt;/strong&gt;&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.legacy&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * ADAPTEE: Closed legacy SDK expecting primitive data types and returning raw status codes.
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LegacyBankingService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;executeLegacyTransaction&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;amountInCents&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;transactionCode&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;"[LEGACY CORE BANKING] Processing on-premise transaction..."&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;printf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" -&amp;gt; Identifier: %s | Amount in Cents: %d\n"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transactionCode&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amountInCents&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Simulation: Amounts greater than zero return legacy success code 200&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amountInCents&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Success&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Error&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  3. The Object Adapter (Anti-Corruption Layer)
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;LegacyBankingAdapter.java (Adapter)&lt;/strong&gt;&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.adapter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.domain.PaymentCharge&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.domain.PaymentResult&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.legacy.LegacyBankingService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.target.PaymentProcessor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.math.BigDecimal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.math.RoundingMode&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * ADAPTER: Implements PaymentProcessor (Target) and wraps LegacyBankingService (Adaptee).
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LegacyBankingAdapter&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;LegacyBankingService&lt;/span&gt; &lt;span class="n"&gt;legacyBankingService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Composition via Dependency Injection&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LegacyBankingAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LegacyBankingService&lt;/span&gt; &lt;span class="n"&gt;legacyBankingService&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;legacyBankingService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;legacyBankingService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;PaymentResult&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentCharge&lt;/span&gt; &lt;span class="n"&gt;charge&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Data Transformation: Convert BigDecimal to total cents (long)&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;amountInCents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;convertToCents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charge&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAmount&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="c1"&gt;// 2. Delegation: Forward translated payload to the Adaptee&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;legacyBankingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeLegacyTransaction&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;amountInCents&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;charge&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTransactionId&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Response Translation: Map primitive status codes to rich domain results&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PaymentResult&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Transaction settled successfully by core banking."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PaymentResult&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Settlement failed. Legacy error code: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;statusCode&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;convertToCents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt; &lt;span class="n"&gt;amount&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;amount&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                     &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setScale&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;RoundingMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HALF_UP&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                     &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;longValueExact&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  4. Client Execution &amp;amp; Demonstration
&lt;/h4&gt;

&lt;p&gt;&lt;b&gt;Click to view OrderService &amp;amp; Main Demonstration Execution&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OrderService.java (Client)&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.client&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.adapter.LegacyBankingAdapter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.domain.PaymentCharge&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.domain.PaymentResult&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.legacy.LegacyBankingService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.article.adapter.target.PaymentProcessor&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.math.BigDecimal&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.UUID&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * CLIENT: Consumes the PaymentProcessor contract without direct coupling to legacy code.
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="n"&gt;paymentProcessor&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;OrderService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="n"&gt;paymentProcessor&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;paymentProcessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paymentProcessor&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;completeCheckout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentCharge&lt;/span&gt; &lt;span class="n"&gt;charge&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;"[CLIENT] Submitting payment request to processor..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;PaymentResult&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paymentProcessor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charge&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;"[CLIENT] Result received: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;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;// 1. Instantiate the legacy SDK (Adaptee)&lt;/span&gt;
        &lt;span class="nc"&gt;LegacyBankingService&lt;/span&gt; &lt;span class="n"&gt;legacySdk&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;LegacyBankingService&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// 2. Wrap the Adaptee with our Adapter&lt;/span&gt;
        &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt; &lt;span class="n"&gt;adapter&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;LegacyBankingAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;legacySdk&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Inject the Adapter into the Client&lt;/span&gt;
        &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="n"&gt;checkout&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;OrderService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;PaymentCharge&lt;/span&gt; &lt;span class="n"&gt;charge&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;PaymentCharge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;randomUUID&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BigDecimal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"250.75"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                &lt;span class="s"&gt;"customer@email.com"&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;checkout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;completeCheckout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;charge&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;
  
  
  2.4 Trade-offs: Pros and Cons
&lt;/h3&gt;

&lt;p&gt;Adopting the Adapter pattern requires evaluating architectural benefits against operational trade-offs:&lt;/p&gt;

&lt;h4&gt;
  
  
  Pros
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adherence to the Single Responsibility Principle (SRP):&lt;/strong&gt; Encapsulates data conversion and contract translation away from the core business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adherence to the Open/Closed Principle (OCP):&lt;/strong&gt; New adapters for additional banking providers or third-party services can be introduced without modifying existing client code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusability of Legacy Code:&lt;/strong&gt; Extends the lifecycle of mission-critical systems without necessitating high-risk complete rewrites.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anti-Corruption Layer:&lt;/strong&gt; Protects the domain model from obsolete terminology, primitive obsession, and vendor-specific data structures.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Cons &amp;amp; Trade-offs
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Increased Structural Complexity:&lt;/strong&gt; Introduces additional interfaces and wrapper classes, increasing the overall number of artifacts in the repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indirection Overhead:&lt;/strong&gt; Adds an extra layer of method delegation and object referencing, though performance impact is negligible in typical enterprise workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk of Conceptual Misalignment:&lt;/strong&gt; If the abstractions between the target and the adaptee differ drastically (such as synchronous calls versus asynchronous queue semantics), the adapter can become overly complex and difficult to maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Conclusion: Wrap-up, Reflections, and Next Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Summary
&lt;/h3&gt;

&lt;p&gt;Throughout this article, we examined how the &lt;strong&gt;Adapter Design Pattern&lt;/strong&gt; serves as a foundational enabler for software evolution and architectural resilience. By mediating communication between mismatched interfaces, it enables modern services to collaborate seamlessly with legacy components and closed third-party SDKs without requiring structural modifications on either side.&lt;/p&gt;

&lt;p&gt;In our payment processing case study, we demonstrated how the Adapter functions as a robust &lt;strong&gt;Anti-Corruption Layer&lt;/strong&gt;: it safeguards the integrity of the core domain, centralizes low-level data conversions, and translates raw status codes into meaningful domain representations. This approach ensures that legacy stability and modern clean architecture can coexist with minimal coupling.&lt;/p&gt;




&lt;h3&gt;
  
  
  3.2 Personal Perspective
&lt;/h3&gt;

&lt;p&gt;For a long time, working with legacy codebases often felt like an invitation to tedious rework. In day-to-day software engineering, refactoring and maintaining systems built on outdated architectures without standardized design can be significantly harder than designing new solutions from the ground up. However, delving into the &lt;strong&gt;Adapter Pattern&lt;/strong&gt; reshapes that perspective: it offers a pragmatic strategy to leverage and extend the lifespan of proven systems, reducing rewrite overhead while reinforcing solid architectural decision-making.&lt;/p&gt;

&lt;p&gt;In practice, the most noticeable benefit is how cleanly the domain logic remains isolated. The adapter acts as a protective boundary, keeping business rules decoupled from primitive type conversions and proprietary response formats, which dramatically improves testability through interfaces and mocks. Nevertheless, applying the pattern demands architectural discipline: it should not be treated as a catch-all fix. Forcing an adapter between components with fundamentally incompatible concurrency models, transaction boundaries, or domain concepts can introduce accidental complexity and obscure underlying system flaws.&lt;/p&gt;

&lt;p&gt;Looking at modern trends—particularly with the surge of AI-driven architectures, multi-agent frameworks, and extensive third-party API integrations—the Adapter pattern remains exceptionally relevant. It provides a clean, standardized mechanism to plug, swap, and orchestrate heterogeneous external services with minimal friction, proving that classical object-oriented design principles remain vital in modern distributed engineering.&lt;/p&gt;




&lt;h3&gt;
  
  
  3.3 Discussion
&lt;/h3&gt;

&lt;p&gt;Have you implemented the &lt;strong&gt;Adapter Pattern&lt;/strong&gt; in your projects to integrate legacy subsystems, proprietary SDKs, or third-party APIs? What was the biggest hurdle you encountered when mapping divergent data contracts or handling incompatible error models?&lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;Share your insights and experiences in the comments below!&lt;/strong&gt; Let's discuss lessons learned and best practices for bridging legacy and modern architectures.&lt;/p&gt;

</description>
      <category>java</category>
      <category>designpatterns</category>
      <category>architecture</category>
      <category>oop</category>
    </item>
  </channel>
</rss>
