Menu
Coddy logo textTech

Padrão Strategy

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy — lição 69 de 87.

O Strategy Pattern é um padrão de projeto comportamental que permite definir uma família de algoritmos, encapsular cada um em sua própria classe e torná-los intercambiáveis. Em vez de codificar rigidamente um comportamento específico, você pode trocar os algoritmos em tempo de execução sem alterar o código que os utiliza.

Imagine um sistema de pagamento que suporte múltiplos métodos de pagamento. Sem o Padrão Strategy, você acabaria com uma lógica condicional bagunçada. Com ele, cada método de pagamento se torna sua própria estratégia:

interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via Credit Card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via PayPal");
    }
}

A classe context mantém uma referência a uma estratégia e delega o trabalho a ela. A chave é que o contexto não sabe qual estratégia concreta está usando — ele conhece apenas a interface:

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }
    
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

Agora você pode alterar o comportamento de pagamento dinamicamente:

ShoppingCart cart = new ShoppingCart();

cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100);  // Pago 100 via Cartão de Crédito

cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50);   // Pago 50 via PayPal

O Padrão Strategy brilha quando você tem várias maneiras de realizar uma ação e deseja alternar entre elas facilmente. Adicionar um novo método de pagamento significa simplesmente criar uma nova classe que implementa PaymentStrategy—nenhuma alteração no código existente é necessária.

challenge icon

Desafio

Fácil

Vamos construir um sistema de formatação de texto usando o Strategy Pattern! Você criará um sistema onde diferentes estratégias de formatação podem ser trocadas em tempo de execução para transformar o texto de várias maneiras — perfeito para uma aplicação que precisa suportar múltiplos formatos de saída.

Você organizará seu código em quatro arquivos:

  • TextFormatter.java: Defina a interface TextFormatter que todas as estratégias de formatação implementarão. Ela deve declarar um único método String format(String text) que recebe uma string e retorna a versão formatada.
  • Formatters.java: Crie três estratégias concretas que implementam sua interface TextFormatter:

    UpperCaseFormatter - transforma o texto em todas as letras maiúsculas.

    LowerCaseFormatter - transforma o texto em todas as letras minúsculas.

    TitleCaseFormatter - coloca a primeira letra de cada palavra em maiúscula, mantendo o restante em minúscula. As palavras são separadas por espaços.

  • TextEditor.java: Crie a classe de contexto que utiliza uma estratégia de formatação. Seu TextEditor deve ter:

    Um campo privado para armazenar a estratégia TextFormatter atual.

    Um método setFormatter(TextFormatter formatter) que altera a estratégia de formatação ativa.

    Um método publishText(String text) que aplica o formatador atual ao texto e imprime Published: [formatted text]. Se nenhum formatador tiver sido definido, ele deve imprimir Published: [original text] sem alterações.

  • Main.java: Reúna seu sistema de estratégia! Você receberá duas entradas: o texto a ser formatado (String) e o estilo de formatação (String: "upper", "lower", ou "title").

    Crie um TextEditor e primeiro chame publishText com seu texto de entrada antes de definir qualquer formatador (demonstrando o comportamento padrão).

    Em seguida, com base na entrada de estilo, defina a estratégia de formatador apropriada e chame publishText novamente com o mesmo texto para mostrar o resultado formatado.

Você receberá duas entradas em ordem: o texto a ser formatado (String) e o estilo de formatação (String).

Por exemplo, com as entradas hello world e title, sua saída seria:

Published: hello world
Published: Hello World

Observe como o TextEditor não sabe nada sobre a lógica de formatação específica — ele simplesmente delega para qualquer estratégia que esteja definida no momento. Isso torna trivial a adição de novos estilos de formatação sem tocar no código do editor!

Folha de consulta

O Strategy Pattern (Padrão de Estratégia) é um padrão de design comportamental que define uma família de algoritmos, encapsula cada um em sua própria classe e os torna intercambiáveis. Ele permite trocar algoritmos em tempo de execução sem alterar o código que os utiliza.

Componentes Chave

Strategy Interface: Define a interface comum para todas as estratégias concretas.

interface PaymentStrategy {
    void pay(int amount);
}

Concrete Strategies: Implementam a interface de estratégia com algoritmos específicos.

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via Credit Card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via PayPal");
    }
}

Context Class: Mantém uma referência para uma estratégia e delega o trabalho a ela. O contexto conhece apenas a interface, não a implementação concreta.

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }
    
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

Uso

As estratégias podem ser alteradas dinamicamente em tempo de execução:

ShoppingCart cart = new ShoppingCart();

cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100);  // Paid 100 via Credit Card

cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50);   // Paid 50 via PayPal

Benefícios

O Strategy Pattern é ideal quando você tem várias maneiras de realizar uma ação e deseja alternar entre elas facilmente. Adicionar uma nova estratégia significa simplesmente criar uma nova classe que implementa a interface de estratégia — nenhuma alteração no código existente é necessária.

Experimente você mesmo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String text = scanner.nextLine();
        String style = scanner.nextLine();
        
        // TODO: Criar uma instância de TextEditor
        
        // TODO: Chamar publishText com o texto de entrada (antes de definir qualquer formatador)
        
        // TODO: Com base na entrada de estilo ("upper", "lower" ou "title"),
        // definir o formatador apropriado e chamar publishText novamente
        
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos