<?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: Emanuel Antônio Lima Rocha</title>
    <description>The latest articles on DEV Community by Emanuel Antônio Lima Rocha (@emanuel_lima).</description>
    <link>https://dev.to/emanuel_lima</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%2F4123476%2F765de87d-dce7-4b52-992b-34d1638a1e87.png</url>
      <title>DEV Community: Emanuel Antônio Lima Rocha</title>
      <link>https://dev.to/emanuel_lima</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emanuel_lima"/>
    <language>en</language>
    <item>
      <title>Strategy em Java para desacoplar o cálculo de frete</title>
      <dc:creator>Emanuel Antônio Lima Rocha</dc:creator>
      <pubDate>Sun, 13 Sep 2026 18:22:41 +0000</pubDate>
      <link>https://dev.to/emanuel_lima/strategy-em-java-para-desacoplar-o-calculo-de-frete-22p6</link>
      <guid>https://dev.to/emanuel_lima/strategy-em-java-para-desacoplar-o-calculo-de-frete-22p6</guid>
      <description>&lt;p&gt;Autor: Emanuel Antônio Lima Rocha&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 Base fundamental&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introdução&lt;/strong&gt;&lt;br&gt;
O Strategy é um padrão comportamental que reúne maneiras alternativas de executar uma operação sob um contrato comum, permitindo escolher a implementação usada pelo contexto. No catálogo de Gamma e colaboradores, ele pertence à categoria dos padrões comportamentais [1]. A separação entre contexto, interface e estratégias concretas permite variar o algoritmo por composição [2].&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O problema de design&lt;/strong&gt;&lt;br&gt;
Considere um checkout legado que calcula frete econômico e expresso dentro do mesmo método. Cada modalidade acrescenta condições e regras nesse ponto central. No estudo de caso deste artigo, o gargalo é a dificuldade de manutenção: alterar uma tarifa exige editar código que também trata outras modalidades. Trata-se de um cenário didático verossímil, e não de um relato de uma empresa ou de resultados medidos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como o padrão funciona&lt;/strong&gt;&lt;br&gt;
O contexto mantém uma referência ao contrato da estratégia e delega a operação à implementação recebida. O cliente escolhe a estratégia; o contexto não precisa conhecer sua classe concreta. A analogia é a escolha de uma modalidade de entrega: o checkout pede uma cotação, enquanto cada modalidade decide como calculá-la [2]. No exemplo, CalculadoraFrete é o contexto, FreteStrategy é o contrato e FreteEconomico e FreteExpresso são as alternativas. Main faz a composição dos objetos.&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;2 Desenvolvimento&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estudo de caso de mercado&lt;/strong&gt;&lt;br&gt;
Uma loja virtual precisa acrescentar modalidades de frete sem concentrar todas as fórmulas no checkout. A proposta é extrair cada regra para uma estratégia. Para tornar o exemplo reproduzível, as tarifas são fictícias: econômico custa R$ 8,00 mais R$ 2,50 por quilograma; expresso custa R$ 15,00 mais R$ 4,00 por quilograma. Um pedido de 3 kg resulta em R$ 15,50 ou R$ 27,00, respectivamente. Esses valores são premissas do exemplo, não preços de transportadoras.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagrama de classes&lt;/strong&gt;&lt;br&gt;
A Figura 1 representa as classes do código. A seta com ponta vazada indica implementação da interface; a seta de CalculadoraFrete indica navegação para uma estratégia. Main cria Pedido e CalculadoraFrete e seleciona as implementações. Pedido é parâmetro de calcular nas três classes e na interface; essas dependências de parâmetro estão descritas aqui para manter a figura legível. O símbolo + indica acesso público, - privado e ~ acesso de pacote.&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%2F3kf0sw9gs1jyl74p5hnw.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%2F3kf0sw9gs1jyl74p5hnw.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Figura 1 — Estrutura UML do Strategy aplicado ao frete. Fonte: elaboração própria, com base na estrutura do padrão [2].&lt;/strong&gt;&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;Arquitetura de software&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Onde o padrão se encaixa&lt;/strong&gt;&lt;br&gt;
Na arquitetura proposta, o cliente chama a API de checkout por HTTPS. A API valida o pedido e a modalidade, seleciona uma estratégia e cria uma CalculadoraFrete para aquela solicitação. A calculadora delega o cálculo à regra escolhida. A API acessa o banco para consultar o pedido e registrar a cotação. Apenas uma estratégia é executada por cotação; as duas setas representam alternativas, não execução paralela.&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%2Fadeqqi6egg0qwrc0dpo8.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%2Fadeqqi6egg0qwrc0dpo8.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Figura 2 — Arquitetura de alto nível do checkout e localização do Strategy. Fonte: elaboração própria.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Escopo da implementação&lt;/strong&gt;&lt;br&gt;
O código abaixo implementa o núcleo de cálculo e um cliente de console. Main exerce o papel de seleção que a API teria. HTTP e persistência contextualizam o sistema na Figura 2 e não são implementados neste exemplo. As estratégias usam regras locais; não há chamada a transportadoras externas. CEP, peso cubado, restrições de atendimento e prazo precisariam ser modelados antes de uma adoção real. Essa delimitação permite avaliar o padrão sem simular uma integração que o código não executa.&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;Implementação em Java&lt;/strong&gt;&lt;br&gt;
Arquivo Main.java — Java 17 ou superior. BigDecimal evita a representação binária de double; as constantes são construídas a partir de strings. O arredondamento HALF_UP com duas casas é uma decisão explícita deste exemplo [3].&lt;br&gt;
import java.math.BigDecimal;&lt;br&gt;
import java.math.RoundingMode;&lt;br&gt;
import java.util.Map;&lt;br&gt;
import java.util.Objects;&lt;/p&gt;

&lt;p&gt;public class Main {&lt;br&gt;
    public static void main(String[] args) {&lt;br&gt;
        var estrategias = Map.of(&lt;br&gt;
            "economico", new FreteEconomico(),&lt;br&gt;
            "expresso", new FreteExpresso());&lt;br&gt;
        String modalidade = args.length == 0 ? "economico" : args[0];&lt;br&gt;
        FreteStrategy estrategia = estrategias.get(modalidade);&lt;br&gt;
        if (estrategia == null) {&lt;br&gt;
            throw new IllegalArgumentException("Modalidade inválida");&lt;br&gt;
        }&lt;br&gt;
        var pedido = new Pedido(new BigDecimal("3.00"));&lt;br&gt;
        var calculadora = new CalculadoraFrete(estrategia);&lt;br&gt;
        System.out.println("Frete: R$ " + calculadora.calcular(pedido));&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;record Pedido(BigDecimal pesoKg) {&lt;br&gt;
    Pedido {&lt;br&gt;
        Objects.requireNonNull(pesoKg, "Peso obrigatório");&lt;br&gt;
        if (pesoKg.signum() &amp;lt;= 0) {&lt;br&gt;
            throw new IllegalArgumentException("Peso deve ser positivo");&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;interface FreteStrategy {&lt;br&gt;
    BigDecimal calcular(Pedido pedido);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;strong&gt;Estratégias e contexto&lt;/strong&gt;&lt;br&gt;
final class FreteEconomico implements FreteStrategy {&lt;br&gt;
    &lt;a class="mentioned-user" href="https://dev.to/override"&gt;@override&lt;/a&gt;&lt;br&gt;
    public BigDecimal calcular(Pedido pedido) {&lt;br&gt;
        return new BigDecimal("8.00")&lt;br&gt;
            .add(pedido.pesoKg().multiply(new BigDecimal("2.50")))&lt;br&gt;
            .setScale(2, RoundingMode.HALF_UP);&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;final class FreteExpresso implements FreteStrategy {&lt;br&gt;
    &lt;a class="mentioned-user" href="https://dev.to/override"&gt;@override&lt;/a&gt;&lt;br&gt;
    public BigDecimal calcular(Pedido pedido) {&lt;br&gt;
        return new BigDecimal("15.00")&lt;br&gt;
            .add(pedido.pesoKg().multiply(new BigDecimal("4.00")))&lt;br&gt;
            .setScale(2, RoundingMode.HALF_UP);&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;final class CalculadoraFrete {&lt;br&gt;
    private final FreteStrategy estrategia;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CalculadoraFrete(FreteStrategy estrategia) {
    this.estrategia = Objects.requireNonNull(estrategia);
}

BigDecimal calcular(Pedido pedido) {
    return estrategia.calcular(Objects.requireNonNull(pedido));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;strong&gt;Execução e análise da solução&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como executar&lt;/strong&gt;&lt;br&gt;
Execute java Main.java economico para obter Frete: R$ 15.50; execute java Main.java expresso para obter Frete: R$ 27.00. Também é possível compilar com javac Main.java e executar java Main economico. O ponto decimal vem da representação textual de BigDecimal; uma interface brasileira deve formatar a moeda para exibição.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correspondência entre código e diagrama&lt;/strong&gt;&lt;br&gt;
Pedido valida um peso obrigatório e positivo. FreteStrategy define calcular(Pedido). As duas classes concretas implementam esse método. CalculadoraFrete guarda uma referência final à interface e delega a chamada. Main usa um registro de estratégias por nome e rejeita modalidades desconhecidas. A escolha muda entre solicitações pela construção de outro contexto, sem um setter compartilhado. Nenhuma classe mostrada na UML exige um framework.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vantagens observadas no desenho&lt;/strong&gt;&lt;br&gt;
Cada fórmula fica em uma classe específica, o que permite revisar e testar a regra isoladamente. O contexto permanece igual quando uma nova implementação é adicionada. A composição evita herdar uma calculadora para cada modalidade [2]. Neste desenho, adicionar uma modalidade exige criar a estratégia e atualizar o registro no cliente; a configuração ainda precisa mudar, embora CalculadoraFrete permaneça intacta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custos e limites&lt;/strong&gt;&lt;br&gt;
O projeto passa a ter mais classes e um ponto de seleção que precisa conhecer as modalidades. Regras muito simples e estáveis podem não justificar essa estrutura [2]. No exemplo, a validação de peso é comum, mas cada estratégia é responsável por preservar o contrato do resultado. Uma evolução com APIs externas exigiria definir falhas, timeout e validade da cotação. Strategy organiza algoritmos; por si só não cria filas, tolerância a falhas ou escalabilidade. Não foram usados benchmarks para sustentar ganhos de latência.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verificações relevantes&lt;/strong&gt;&lt;br&gt;
A validação deve cobrir as duas tarifas para 3 kg, peso zero ou negativo, peso nulo, modalidade desconhecida e pesos fracionários. O caso de 1,333 kg econômico deve resultar em 11,33 após arredondamento. Essas verificações protegem regras de negócio e o contrato comum, em vez de apenas conferir a existência das classes.&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;3 Conclusão&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Resumo&lt;/strong&gt;&lt;br&gt;
A solução retira as fórmulas de frete do ponto central do checkout e as coloca em implementações substituíveis. O valor arquitetural está na separação de responsabilidades e na possibilidade de acrescentar regras preservando o contexto. O estudo de caso mostra como aplicar o Strategy a um problema de manutenção, com escopo e limitações explícitos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visão pessoal&lt;/strong&gt;&lt;br&gt;
Minha leitura deste estudo de caso é que o aspecto mais útil do Strategy está em identificar o comportamento que varia antes de criar novas classes. Considero a solução adequada quando modalidades evoluem de forma independente. Para poucas regras estáveis, eu avaliaria uma implementação mais simples. Aprender o padrão exige entender a delegação e os seus custos, além de reconhecer a estrutura no diagrama.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pergunta para os leitores&lt;/strong&gt;&lt;br&gt;
No seu projeto, qual conjunto de condicionais poderia ser transformado em estratégias, e o que justificaria essa mudança?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referências&lt;/strong&gt;&lt;br&gt;
[1] GAMMA, Erich; HELM, Richard; JOHNSON, Ralph; VLISSIDES, John. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1994. Catálogo bibliográfico da editora, com Strategy na categoria comportamental. Disponível em: &lt;a href="https://www.informit.com/store/design-patterns-elements-of-reusable-object-oriented-9780321770462" rel="noopener noreferrer"&gt;https://www.informit.com/store/design-patterns-elements-of-reusable-object-oriented-9780321770462&lt;/a&gt;. Acesso em: 13 set. 2026.&lt;br&gt;
[2] REFACTORING GURU. Strategy. Estrutura, aplicação e trade-offs do padrão. Disponível em: &lt;a href="https://refactoring.guru/design-patterns/strategy" rel="noopener noreferrer"&gt;https://refactoring.guru/design-patterns/strategy&lt;/a&gt;. Acesso em: 13 set. 2026.&lt;br&gt;
[3] ORACLE. Java Platform Standard Edition 21. BigDecimal. Documentação oficial da API. Disponível em: &lt;a href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/math/BigDecimal.html" rel="noopener noreferrer"&gt;https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/math/BigDecimal.html&lt;/a&gt;. Acesso em: 13 set. 2026.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>java</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
