<?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: Maxwell Anabil</title>
    <description>The latest articles on DEV Community by Maxwell Anabil (@maxwellsilvadev).</description>
    <link>https://dev.to/maxwellsilvadev</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%2F4118092%2F27b0b311-e847-4dbe-ac0f-6c7d973e5b0f.png</url>
      <title>DEV Community: Maxwell Anabil</title>
      <link>https://dev.to/maxwellsilvadev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maxwellsilvadev"/>
    <language>en</language>
    <item>
      <title>Adapter Pattern em Java: integrando novas transportadoras sem quebrar um sistema legado</title>
      <dc:creator>Maxwell Anabil</dc:creator>
      <pubDate>Wed, 09 Sep 2026 19:29:59 +0000</pubDate>
      <link>https://dev.to/maxwellsilvadev/adapter-pattern-em-java-integrando-novas-transportadoras-sem-quebrar-um-sistema-legado-4a8g</link>
      <guid>https://dev.to/maxwellsilvadev/adapter-pattern-em-java-integrando-novas-transportadoras-sem-quebrar-um-sistema-legado-4a8g</guid>
      <description>&lt;p&gt;&lt;strong&gt;Maxwell Anabil Macabeu da Silva&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Bacharelado em Engenharia de Software — UniEvangélica&lt;br&gt;&lt;br&gt;
Anápolis — Goiás — Brasil&lt;/p&gt;
&lt;h2&gt;
  
  
  Resumo
&lt;/h2&gt;

&lt;p&gt;Sistemas de e-commerce dependem de integrações com serviços externos, como gateways de pagamento, plataformas de logística e transportadoras. Um problema recorrente aparece quando cada fornecedor disponibiliza uma API diferente, com métodos, formatos de dados e estruturas de resposta incompatíveis com o sistema existente.&lt;/p&gt;

&lt;p&gt;Neste artigo apresento a aplicação do &lt;strong&gt;Adapter Pattern&lt;/strong&gt;, um padrão estrutural do catálogo GoF, em um cenário de integração de transportadoras dentro de um sistema de e-commerce desenvolvido em Java.&lt;/p&gt;

&lt;p&gt;A proposta é criar uma interface padrão utilizada pelo sistema e implementar adaptadores responsáveis por traduzir a comunicação com diferentes APIs externas. Dessa forma, o sistema principal não precisa conhecer os detalhes específicos de cada transportadora.&lt;/p&gt;

&lt;p&gt;Além da explicação do padrão, será apresentado um estudo de caso, um diagrama UML de classes, uma visão de arquitetura, uma implementação em Java e uma análise das vantagens e dos trade-offs envolvidos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Palavras-chave:&lt;/strong&gt; Adapter Pattern; Design Patterns; Java; Engenharia de Software; APIs; Integração de Sistemas; E-commerce.&lt;/p&gt;


&lt;h1&gt;
  
  
  1. Base Fundamental
&lt;/h1&gt;
&lt;h2&gt;
  
  
  1.1 O que são Design Patterns?
&lt;/h2&gt;

&lt;p&gt;Durante o desenvolvimento de software, alguns problemas aparecem repetidamente em diferentes projetos.&lt;/p&gt;

&lt;p&gt;Como organizar a criação de objetos? Como permitir que comportamentos sejam alterados sem modificar várias partes do sistema? Como integrar sistemas que possuem interfaces incompatíveis?&lt;/p&gt;

&lt;p&gt;Os &lt;strong&gt;Design Patterns&lt;/strong&gt;, ou padrões de projeto, representam soluções conhecidas e reutilizáveis para problemas recorrentes de design de software.&lt;/p&gt;

&lt;p&gt;Eles não são códigos prontos que simplesmente copiamos para o projeto. Na realidade, são maneiras de estruturar classes e responsabilidades para resolver determinados tipos de problema.&lt;/p&gt;

&lt;p&gt;Os padrões originalmente apresentados pelo chamado &lt;strong&gt;Gang of Four (GoF)&lt;/strong&gt; são geralmente divididos em três grupos:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Categoria&lt;/th&gt;
&lt;th&gt;Objetivo&lt;/th&gt;
&lt;th&gt;Exemplos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Criacionais&lt;/td&gt;
&lt;td&gt;Organizam a criação de objetos&lt;/td&gt;
&lt;td&gt;Factory Method, Builder, Singleton&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estruturais&lt;/td&gt;
&lt;td&gt;Organizam como objetos e classes se relacionam&lt;/td&gt;
&lt;td&gt;Adapter, Decorator, Facade&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comportamentais&lt;/td&gt;
&lt;td&gt;Organizam responsabilidades e comportamentos&lt;/td&gt;
&lt;td&gt;Strategy, Observer, Command&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;O padrão abordado neste artigo é o &lt;strong&gt;Adapter Pattern&lt;/strong&gt;, pertencente à categoria dos padrões &lt;strong&gt;estruturais&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  1.2 O problema: quando cada API fala uma língua diferente
&lt;/h2&gt;

&lt;p&gt;Imagine um sistema de e-commerce que possui um módulo responsável por calcular o valor do frete de um pedido.&lt;/p&gt;

&lt;p&gt;Inicialmente, a empresa utilizava apenas uma transportadora. O código poderia ser semelhante a:&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;ShippingService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;LegacyCarrierClient&lt;/span&gt; &lt;span class="n"&gt;client&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;calculateShipping&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;originZip&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;destinationZip&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;weightInGrams&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;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calculate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;originZip&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;destinationZip&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;weightInGrams&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;Enquanto existe apenas uma integração, essa estrutura parece suficiente.&lt;/p&gt;

&lt;p&gt;O problema aparece quando a empresa decide oferecer mais opções de entrega. Uma segunda transportadora pode possuir algo semelhante a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;fastShipClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRate&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;FastShipPayload&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;origin&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;weightInKg&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;Observe que as duas APIs não trabalham da mesma maneira.&lt;/p&gt;

&lt;p&gt;Uma pode utilizar peso em gramas, parâmetros separados e valor retornado em centavos. Outra pode utilizar peso em quilogramas, um objeto de requisição e valor retornado como &lt;code&gt;BigDecimal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O sistema começa então a acumular verificações:&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;carrier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LEGACY"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// chama API da primeira transportadora&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;carrier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FAST_SHIP"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// converte peso&lt;/span&gt;
    &lt;span class="c1"&gt;// cria payload&lt;/span&gt;
    &lt;span class="c1"&gt;// chama outra API&lt;/span&gt;
    &lt;span class="c1"&gt;// converte resposta&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;carrier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OUTRA_TRANSPORTADORA"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// outra implementação&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quanto mais integrações surgem, maior fica esse código.&lt;/p&gt;

&lt;p&gt;Além disso, o &lt;code&gt;ShippingService&lt;/code&gt; passa a conhecer detalhes que não deveriam fazer parte de sua responsabilidade, como formato de requisição de cada fornecedor, unidades de medida, nomes de métodos externos, estruturas de resposta e tratamento específico de cada API.&lt;/p&gt;

&lt;p&gt;É exatamente nesse tipo de situação que o &lt;strong&gt;Adapter Pattern&lt;/strong&gt; pode ajudar.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.3 Como funciona o Adapter Pattern?
&lt;/h2&gt;

&lt;p&gt;A palavra &lt;em&gt;adapter&lt;/em&gt; significa &lt;strong&gt;adaptador&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Uma analogia simples é um adaptador de tomada. Você possui um dispositivo com um padrão de tomada, mas chega a um local onde a tomada possui outro formato. Em vez de modificar o aparelho ou a instalação elétrica, coloca um adaptador entre os dois.&lt;/p&gt;

&lt;p&gt;No desenvolvimento de software, a ideia é semelhante:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sistema existente
       ↓
Interface conhecida pelo sistema
       ↓
Adapter
       ↓
API externa incompatível
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Adapter recebe uma chamada utilizando o formato esperado pelo sistema e realiza a tradução necessária para o formato exigido pelo serviço externo.&lt;/p&gt;

&lt;p&gt;Normalmente temos três participantes principais:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Target:&lt;/strong&gt; interface que o sistema gostaria de utilizar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adapter:&lt;/strong&gt; implementa essa interface e converte a chamada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptee:&lt;/strong&gt; classe ou API existente que possui uma interface incompatível.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No nosso exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target
ShippingProvider

Adapters
LegacyCarrierAdapter
FastShipAdapter

Adaptees
LegacyCarrierClient
FastShipClient
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim, o restante do sistema trabalha apenas com &lt;code&gt;ShippingProvider&lt;/code&gt; e não precisa saber qual API realmente está por trás daquele objeto.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.4 Adapter não é Strategy
&lt;/h2&gt;

&lt;p&gt;Os dois padrões podem parecer semelhantes porque ambos utilizam interfaces e composição. Porém, resolvem problemas diferentes.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Strategy Pattern&lt;/strong&gt; normalmente é utilizado quando existem diferentes algoritmos capazes de executar uma mesma tarefa.&lt;/p&gt;

&lt;p&gt;Já o &lt;strong&gt;Adapter Pattern&lt;/strong&gt; é utilizado principalmente quando queremos tornar &lt;strong&gt;interfaces incompatíveis compatíveis&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No nosso cenário, nossa aplicação espera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ShippingRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;mas uma API externa oferece:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;originZip&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;destinationZip&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weightGrams&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e outra oferece:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;getRate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FastShipPayload&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Adapter cria uma camada de tradução entre essas interfaces.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Desenvolvimento
&lt;/h1&gt;

&lt;h2&gt;
  
  
  2.1 Cenário do Mundo Real
&lt;/h2&gt;

&lt;p&gt;Considere um e-commerce que vende produtos para diferentes regiões e precisa calcular o frete durante o checkout.&lt;/p&gt;

&lt;p&gt;O fluxo é aproximadamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cliente seleciona os produtos
          ↓
Informa o endereço
          ↓
Sistema solicita cotações
          ↓
Transportadoras calculam o frete
          ↓
Sistema apresenta preço e prazo
          ↓
Cliente escolhe a opção
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inicialmente, o sistema possuía integração apenas com uma transportadora. Com o crescimento da operação, surgiu a necessidade de conectar novos provedores logísticos.&lt;/p&gt;

&lt;p&gt;Porém, cada fornecedor possuía sua própria API.&lt;/p&gt;

&lt;p&gt;Um deles trabalhava com peso em &lt;strong&gt;gramas&lt;/strong&gt;, enquanto outro utilizava &lt;strong&gt;quilogramas&lt;/strong&gt;. Um retornava valores em &lt;strong&gt;centavos&lt;/strong&gt;, enquanto outro retornava &lt;code&gt;BigDecimal&lt;/code&gt;. Um utilizava vários parâmetros no método, enquanto outro esperava um objeto de requisição.&lt;/p&gt;

&lt;p&gt;Alterar o &lt;code&gt;ShippingService&lt;/code&gt; sempre que uma nova integração fosse adicionada faria com que o serviço se tornasse cada vez mais acoplado às APIs externas.&lt;/p&gt;

&lt;p&gt;A solução escolhida é definir uma interface comum chamada &lt;code&gt;ShippingProvider&lt;/code&gt;. Cada API externa recebe então seu próprio Adapter.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.2 Diagrama UML de Classes
&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%2Fnt8nyk8eipwa54pyc8kd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnt8nyk8eipwa54pyc8kd.png" alt="Diagrama UML do Adapter Pattern aplicado ao serviço de fretes" width="800" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figura 1 — Diagrama UML do Adapter Pattern aplicado ao serviço de fretes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O ponto mais importante do diagrama é observar que o &lt;code&gt;ShippingService&lt;/code&gt; depende apenas de &lt;code&gt;ShippingProvider&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ele não conhece diretamente &lt;code&gt;LegacyCarrierClient&lt;/code&gt; nem &lt;code&gt;FastShipClient&lt;/code&gt;. Esses detalhes ficam escondidos dentro dos adapters.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.3 Arquitetura de Software
&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%2Fm46ixn36y26drsace521.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm46ixn36y26drsace521.png" alt="Arquitetura de alto nível do sistema de cotação de fretes" width="799" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figura 2 — Arquitetura de alto nível do sistema de cotação de fretes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O cliente não entra em contato diretamente com as transportadoras.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;Order Service&lt;/code&gt; solicita ao &lt;code&gt;Shipping Service&lt;/code&gt; uma cotação. Dentro do &lt;code&gt;Shipping Service&lt;/code&gt;, os adapters ficam responsáveis por conversar com cada API externa.&lt;/p&gt;

&lt;p&gt;Essa separação é importante porque uma alteração realizada por uma transportadora afeta principalmente seu Adapter, em vez de espalhar modificações pelo restante da aplicação.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.4 Implementação em Java
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.4.1 Representando a solicitação de frete
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&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="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;ShippingRequest&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;originZip&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;destinationZip&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;weightKg&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;ShippingRequest&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;originZip&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;destinationZip&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;weightKg&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;weightKg&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;lt;=&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;"O peso deve ser maior que zero."&lt;/span&gt;
            &lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Independentemente da transportadora utilizada, nosso sistema trabalhará internamente com peso em quilogramas.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4.2 Representando a resposta
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&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="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;ShippingQuote&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;provider&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;price&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;deliveryDays&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;Agora qualquer transportadora utilizada pelo sistema deverá fornecer nome do provedor, preço e prazo de entrega.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4.3 Criando a interface padrão
&lt;/h3&gt;

&lt;p&gt;Este é o nosso &lt;strong&gt;Target&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ShippingProvider&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;ShippingQuote&lt;/span&gt; &lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ShippingRequest&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;ShippingService&lt;/code&gt; conhecerá somente essa interface.&lt;/p&gt;

&lt;p&gt;Ele não precisa conhecer nenhuma API externa diretamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4.4 API da primeira transportadora
&lt;/h3&gt;

&lt;p&gt;Imagine que uma integração antiga utiliza esta interface:&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;interface&lt;/span&gt; &lt;span class="nc"&gt;LegacyCarrierClient&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;LegacyCarrierResponse&lt;/span&gt; &lt;span class="nf"&gt;calculate&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;originZip&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;destinationZip&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;weightInGrams&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;E retorna:&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="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;LegacyCarrierResponse&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;priceInCents&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;estimatedDays&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;Nosso sistema trabalha com quilogramas e &lt;code&gt;BigDecimal&lt;/code&gt;, enquanto essa integração utiliza gramas e centavos.&lt;/p&gt;

&lt;p&gt;As interfaces são incompatíveis.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4.5 Criando o primeiro Adapter
&lt;/h3&gt;

&lt;p&gt;É aqui que entra o padrã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="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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LegacyCarrierAdapter&lt;/span&gt;
        &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ShippingProvider&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;LegacyCarrierClient&lt;/span&gt; &lt;span class="n"&gt;client&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;LegacyCarrierAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;LegacyCarrierClient&lt;/span&gt; &lt;span class="n"&gt;client&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&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;ShippingQuote&lt;/span&gt; &lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;ShippingRequest&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;weightInGrams&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;weightKg&lt;/span&gt;&lt;span class="o"&gt;()&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;1000&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;intValueExact&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;LegacyCarrierResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calculate&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;originZip&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;destinationZip&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
                        &lt;span class="n"&gt;weightInGrams&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;price&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="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;priceInCents&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;movePointLeft&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ShippingQuote&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"Legacy Carrier"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;estimatedDays&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que toda a incompatibilidade ficou dentro dessa classe.&lt;/p&gt;

&lt;p&gt;O Adapter realiza as conversões necessárias e transforma a resposta externa em um &lt;code&gt;ShippingQuote&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O restante do sistema não precisa conhecer nenhuma dessas conversões.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4.6 Integrando uma segunda transportadora
&lt;/h3&gt;

&lt;p&gt;Agora imagine uma API mais moderna:&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;interface&lt;/span&gt; &lt;span class="nc"&gt;FastShipClient&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;FastShipRate&lt;/span&gt; &lt;span class="nf"&gt;getRate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;FastShipPayload&lt;/span&gt; &lt;span class="n"&gt;payload&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;Seu payload:&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;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="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;FastShipPayload&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;from&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;to&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;weight&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;E sua resposta:&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;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="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;FastShipRate&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;businessDays&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;Novamente, podemos criar um Adapter:&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;FastShipAdapter&lt;/span&gt;
        &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ShippingProvider&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;FastShipClient&lt;/span&gt; &lt;span class="n"&gt;client&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;FastShipAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;FastShipClient&lt;/span&gt; &lt;span class="n"&gt;client&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&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;ShippingQuote&lt;/span&gt; &lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;ShippingRequest&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;FastShipPayload&lt;/span&gt; &lt;span class="n"&gt;payload&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;FastShipPayload&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;originZip&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;destinationZip&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;weightKg&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;FastShipRate&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&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;ShippingQuote&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"Fast Ship"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;response&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;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;businessDays&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apesar de as duas APIs externas serem diferentes, para o restante do sistema elas agora possuem exatamente o mesmo contrato:&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="nc"&gt;ShippingQuote&lt;/span&gt; &lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ShippingRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse é o principal benefício do Adapter Pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4.7 O ShippingService
&lt;/h3&gt;

&lt;p&gt;Agora podemos criar um serviço que recebe diversas implementações de &lt;code&gt;ShippingProvider&lt;/code&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;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Comparator&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.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShippingService&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;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ShippingProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;providers&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;ShippingService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ShippingProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;providers&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;providers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;providers&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;ShippingQuote&lt;/span&gt; &lt;span class="nf"&gt;bestQuote&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;ShippingRequest&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;providers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                        &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;quote&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="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                    &lt;span class="nc"&gt;Comparator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;comparing&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="nl"&gt;ShippingQuote:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;price&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="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="s"&gt;"Nenhuma transportadora disponível."&lt;/span&gt;
                    &lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe que não existe um &lt;code&gt;if&lt;/code&gt; ou &lt;code&gt;switch&lt;/code&gt; para tratar cada transportadora.&lt;/p&gt;

&lt;p&gt;O serviço simplesmente sabe que possui objetos capazes de executar &lt;code&gt;quote(request)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A implementação específica deixa de ser responsabilidade dele.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4.8 Utilizando o serviço
&lt;/h3&gt;

&lt;p&gt;Um exemplo simplificado seria:&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;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.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheckoutDemo&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="nc"&gt;ShippingProvider&lt;/span&gt; &lt;span class="n"&gt;legacyProvider&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;LegacyCarrierAdapter&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;LegacyCarrierClientImpl&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ShippingProvider&lt;/span&gt; &lt;span class="n"&gt;fastShipProvider&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;FastShipAdapter&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;FastShipClientImpl&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ShippingService&lt;/span&gt; &lt;span class="n"&gt;shippingService&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;ShippingService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                                &lt;span class="n"&gt;legacyProvider&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;fastShipProvider&lt;/span&gt;
                        &lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ShippingRequest&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;new&lt;/span&gt; &lt;span class="nf"&gt;ShippingRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="s"&gt;"75000-000"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                        &lt;span class="s"&gt;"74000-000"&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;"2.5"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ShippingQuote&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                &lt;span class="n"&gt;shippingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bestQuote&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="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;"Transportadora: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;provider&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;"Frete: R$ "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&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;"Prazo: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deliveryDays&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="s"&gt;" dias"&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;Se uma terceira transportadora for adicionada posteriormente, podemos criar outra implementação de &lt;code&gt;ShippingProvider&lt;/code&gt; e registrá-la no serviço, sem reescrever a lógica de cálculo existente.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.5 Testabilidade
&lt;/h2&gt;

&lt;p&gt;Outra vantagem dessa estrutura aparece nos testes.&lt;/p&gt;

&lt;p&gt;Podemos testar cada Adapter isoladamente:&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;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&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;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mockito&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Mockito&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;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LegacyCarrierAdapterTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deveConverterQuilogramasParaGramas&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;LegacyCarrierClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                &lt;span class="n"&gt;mock&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LegacyCarrierClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;when&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calculate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"75000-000"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"74000-000"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="mi"&gt;2500&lt;/span&gt;
            &lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;thenReturn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LegacyCarrierResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="mi"&gt;1890&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="mi"&gt;4&lt;/span&gt;
            &lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;LegacyCarrierAdapter&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="nf"&gt;LegacyCarrierAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ShippingRequest&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;new&lt;/span&gt; &lt;span class="nf"&gt;ShippingRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"75000-000"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                    &lt;span class="s"&gt;"74000-000"&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;"2.5"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ShippingQuote&lt;/span&gt; &lt;span class="n"&gt;quote&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="na"&gt;quote&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="n"&gt;assertEquals&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;"18.90"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deliveryDays&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O teste consegue verificar a lógica do Adapter sem precisar executar todo o checkout.&lt;/p&gt;

&lt;p&gt;Isso facilita encontrar erros em conversões e integrações.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.6 Boas práticas aplicadas
&lt;/h2&gt;

&lt;p&gt;Além do Adapter Pattern, algumas decisões ajudam a manter o projeto organizado.&lt;/p&gt;

&lt;p&gt;A aplicação utiliza &lt;strong&gt;injeção de dependência&lt;/strong&gt;, pois os clientes das transportadoras são recebidos pelo construtor dos Adapters em vez de serem criados internamente.&lt;/p&gt;

&lt;p&gt;Também existe uma separação entre os objetos do domínio e os objetos utilizados pelas APIs externas.&lt;/p&gt;

&lt;p&gt;Por exemplo, &lt;code&gt;ShippingRequest&lt;/code&gt; pertence à aplicação, enquanto &lt;code&gt;FastShipPayload&lt;/code&gt; pertence à integração externa.&lt;/p&gt;

&lt;p&gt;Essa separação evita que alterações realizadas por uma transportadora contaminem diretamente os modelos internos do sistema.&lt;/p&gt;

&lt;p&gt;Outro ponto importante é o uso de &lt;code&gt;BigDecimal&lt;/code&gt; para representar valores monetários, evitando problemas comuns de precisão que podem ocorrer com tipos de ponto flutuante.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.7 Prós e Contras do Adapter Pattern
&lt;/h2&gt;

&lt;p&gt;Como qualquer decisão arquitetural, o Adapter Pattern possui benefícios e custos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vantagens
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reduz o acoplamento com bibliotecas e APIs externas.&lt;/li&gt;
&lt;li&gt;Permite manter uma interface consistente dentro da aplicação.&lt;/li&gt;
&lt;li&gt;Facilita a substituição de fornecedores.&lt;/li&gt;
&lt;li&gt;Melhora a testabilidade das integrações.&lt;/li&gt;
&lt;li&gt;Concentra conversões e adaptações em classes específicas.&lt;/li&gt;
&lt;li&gt;Evita espalhar detalhes de APIs externas pelo sistema.&lt;/li&gt;
&lt;li&gt;Facilita adicionar novas integrações.&lt;/li&gt;
&lt;li&gt;Favorece o princípio de responsabilidade única.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Desvantagens e trade-offs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Aumenta o número de classes do projeto.&lt;/li&gt;
&lt;li&gt;Cada API externa exige seu próprio Adapter.&lt;/li&gt;
&lt;li&gt;Mudanças frequentes no fornecedor podem exigir manutenção constante do adaptador.&lt;/li&gt;
&lt;li&gt;Em sistemas muito pequenos, a abstração pode ser desnecessária.&lt;/li&gt;
&lt;li&gt;Uma má implementação pode transformar o Adapter em uma classe com responsabilidades demais.&lt;/li&gt;
&lt;li&gt;O padrão não elimina a complexidade da integração: ele organiza e isola essa complexidade.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Portanto, utilizar Adapter para qualquer integração simples também pode gerar complexidade desnecessária.&lt;/p&gt;

&lt;p&gt;O padrão faz mais sentido quando a interface externa realmente é incompatível com o modelo utilizado pelo restante da aplicação.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Conclusão
&lt;/h1&gt;

&lt;h2&gt;
  
  
  3.1 Resumo
&lt;/h2&gt;

&lt;p&gt;O Adapter Pattern apresenta uma solução simples para um problema comum na engenharia de software: integrar componentes que possuem interfaces diferentes.&lt;/p&gt;

&lt;p&gt;No cenário apresentado, cada transportadora possuía sua própria forma de calcular frete.&lt;/p&gt;

&lt;p&gt;Sem uma camada de adaptação, o &lt;code&gt;ShippingService&lt;/code&gt; precisaria conhecer os detalhes de cada API, criando alto acoplamento e dificultando a manutenção do código.&lt;/p&gt;

&lt;p&gt;Com a criação da interface &lt;code&gt;ShippingProvider&lt;/code&gt;, o sistema passou a trabalhar com um único contrato.&lt;/p&gt;

&lt;p&gt;As classes &lt;code&gt;LegacyCarrierAdapter&lt;/code&gt; e &lt;code&gt;FastShipAdapter&lt;/code&gt; passaram a ser responsáveis por traduzir a comunicação entre o domínio da aplicação e os serviços externos.&lt;/p&gt;

&lt;p&gt;O resultado é uma arquitetura mais desacoplada, extensível e testável.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.2 Visão Pessoal
&lt;/h2&gt;

&lt;p&gt;Ao estudar o Adapter Pattern, o que mais me chamou atenção foi perceber que um Design Pattern não precisa obrigatoriamente envolver uma solução extremamente complexa.&lt;/p&gt;

&lt;p&gt;A ideia do Adapter é relativamente simples: criar uma camada de tradução entre duas interfaces incompatíveis.&lt;/p&gt;

&lt;p&gt;Mesmo sendo simples, essa decisão pode ter um impacto grande na organização de um projeto.&lt;/p&gt;

&lt;p&gt;Antes de estudar esse padrão, seria natural pensar em adaptar cada nova API diretamente dentro do serviço principal utilizando condicionais e conversões.&lt;/p&gt;

&lt;p&gt;Porém, com o Adapter, fica mais claro que os detalhes de integração pertencem a uma classe específica.&lt;/p&gt;

&lt;p&gt;Também percebi que padrões de projeto não devem ser aplicados apenas porque existem. Eles precisam resolver um problema real.&lt;/p&gt;

&lt;p&gt;Se o sistema possuir apenas uma integração simples e que dificilmente será alterada, talvez criar vários níveis de abstração não seja necessário.&lt;/p&gt;

&lt;p&gt;Por outro lado, quando diferentes APIs precisam conviver dentro de um mesmo sistema, o Adapter pode reduzir bastante o acoplamento e tornar futuras alterações mais seguras.&lt;/p&gt;

&lt;p&gt;Para mim, esse foi um dos principais aprendizados: &lt;strong&gt;Design Patterns não servem apenas para deixar o código mais sofisticado, mas para tornar determinadas mudanças mais fáceis de realizar.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3.3 E você?
&lt;/h2&gt;

&lt;p&gt;Você já precisou integrar uma API que possuía uma estrutura completamente diferente da utilizada pelo seu sistema?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usaria o Adapter Pattern nesse cenário ou escolheria outra abordagem?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Compartilhe sua opinião nos comentários.&lt;/p&gt;




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

&lt;p&gt;GAMMA, Erich; HELM, Richard; JOHNSON, Ralph; VLISSIDES, John. &lt;strong&gt;Design Patterns: Elements of Reusable Object-Oriented Software.&lt;/strong&gt; Boston: Addison-Wesley, 1994.&lt;/p&gt;

&lt;p&gt;FOWLER, Martin. &lt;strong&gt;Refactoring: Improving the Design of Existing Code.&lt;/strong&gt; 2. ed. Boston: Addison-Wesley, 2018.&lt;/p&gt;

&lt;p&gt;FREEMAN, Eric; ROBSON, Elisabeth. &lt;strong&gt;Head First Design Patterns.&lt;/strong&gt; 2. ed. Sebastopol: O'Reilly Media, 2020.&lt;/p&gt;

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