Padrão Strategy
Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 69 de 87.
O padrão Strategy é um padrão comportamental de projeto 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 diretamente 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 pagamentos compatível com vários métodos de pagamento. Sem o Strategy Pattern, você acabaria com uma lógica condicional confusa. 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 de contexto mantém uma referência a uma estratégia e delega o trabalho a ela. O ponto principal é 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 PayPalO Padrão Strategy se destaca quando você tem várias maneiras de realizar uma ação e quer alternar entre elas facilmente. Adicionar um novo método de pagamento significa simplesmente criar uma nova classe que implementa PaymentStrategy: não são necessárias alterações no código existente.
Desafio
FácilVamos criar um sistema de formatação de texto usando o Padrão Strategy! Você criará um sistema no qual diferentes estratégias de formatação podem ser trocadas em tempo de execução para transformar texto de várias maneiras, perfeito para uma aplicação que precisa oferecer suporte a vários formatos de saída.
Você organizará seu código em quatro arquivos:
TextFormatter.java: Defina a interfaceTextFormatterque todas as estratégias de formatação implementarão. Ela deve declarar um único métodoString format(String text)que recebe uma string e retorna a versão formatada.Formatters.java: Crie três estratégias concretas que implementem sua interfaceTextFormatter:UpperCaseFormatter- transforma o texto em letras maiúsculas.LowerCaseFormatter- transforma o texto em letras minúsculas.TitleCaseFormatter- coloca em maiúscula a primeira letra de cada palavra, deixando o restante em minúsculas. As palavras são separadas por espaços.TextEditor.java: Crie a classe de contexto que usa uma estratégia de formatação. SeuTextEditordeve ter:Um campo privado para armazenar a estratégia
TextFormatteratual.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 imprimePublished: [formatted text]. Se nenhum formatador tiver sido definido, ele deverá imprimirPublished: [original text]sem alterações.Main.java: Reúna seu sistema de estratégias! Você receberá duas entradas: o texto a ser formatado (String) e o estilo de formatação (String:"upper","lower"ou"title").Crie um
TextEditore primeiro chamepublishTextcom o 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 formatação apropriada e chame
publishTextnovamente com o mesmo texto para mostrar o resultado formatado.
Você receberá duas entradas, nesta 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 WorldObserve como o TextEditor não sabe nada sobre a lógica específica de formatação. Ele simplesmente delega para qualquer estratégia definida no momento. Isso torna trivial adicionar novos estilos de formatação sem alterar o código do editor!
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: Crie uma instância de TextEditor
// TODO: Chame publishText com o texto de entrada (antes de definir qualquer formatador)
// TODO: Com base na entrada de estilo ("upper", "lower" ou "title"),
// defina o formatador apropriado e chame publishText novamente
}
}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
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave thisMétodosCampos (Atributos)Método ConstrutorSobrecarga de ConstrutorRecapitulação - Calculadora Simples4Herança
Herança Básica (extends)A Palavra-chave superSobrescrita de Método (@Override)Encadeamento de ConstrutoresA Classe ObjectHerança Simples e MultinívelPor que não há Herança Múltipla de ClassesRecapitulação - Hierarquia de Funcionários7Métodos Especiais e a Classe Object
Método toString()equals() e hashCode()Método clone()compareTo() e ComparableInterface ComparatorRecapitulação - Ordenação Personalizada2Modificadores de Acesso e Encapsulamento
Visão Geral dos Níveis de AcessoMétodos Getter e SetterOcultação de InformaçõesA Palavra-chave finalRecapitulação - Gerenciador de Conta Bancária5Polimorfismo
Fundamentos de Sobrecarga de MétodosSobrescrita de Métodos (Tempo de Execução)Upcasting e DowncastingO Operador instanceofClasses e Métodos AbstratosRecapitulação - Calculadora de Formas8Conceitos Avançados de OOP
Composição vs HerançaAgregação vs ComposiçãoClasses Internas, Aninhadas e AnônimasEnums e Métodos de EnumRecords (Java 16+)Classes Seladas (Java 17+)11Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão BuilderPadrão ObserverPadrão Strategy3Propriedades de Classe e Membros Estáticos
Variáveis de Instância vs EstáticasMétodos EstáticosBlocos EstáticosConstantes (static final)Recapitulação - Contador e Utilitário6Interfaces e Classes Abstratas
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesDefault e Static em InterfacesClasses Abstratas vs InterfacesInterfaces FuncionaisRecapitulação - Sistema de Pagamento9Generics
Introdução a GenericsClasses GenéricasMétodos GenéricosParâmetros de Tipos DelimitadosWildcards (?, extends, super)Recapitulação - Container Genérico12Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão IteratorPratique por conta própria: Compilador de Java online