Padrão de Design de Estratégia em Java – Tutorial de Exemplo

O padrão de design de estratégia é um dos padrões de design comportamental. O padrão de estratégia é usado quando temos vários algoritmos para uma tarefa específica e o cliente decide a implementação real a ser usada em tempo de execução.

Padrão de Estratégia

O padrão de estratégia também é conhecido como Padrão de Política. Definimos vários algoritmos e deixamos a aplicação cliente passar o algoritmo a ser usado como um parâmetro. Um dos melhores exemplos do padrão de estratégia é o método Collections.sort() que recebe o parâmetro Comparator. Com base nas diferentes implementações das interfaces Comparator, os objetos são classificados de diferentes maneiras. Para o nosso exemplo, tentaremos implementar um simples carrinho de compras onde temos duas estratégias de pagamento – usando cartão de crédito ou usando PayPal. Primeiro de tudo, criaremos a interface para o nosso exemplo de padrão de estratégia, no nosso caso, para pagar o valor passado como argumento. PaymentStrategy.java

package com.journaldev.design.strategy;

public interface PaymentStrategy {

	public void pay(int amount);
}

Agora teremos que criar uma implementação concreta dos algoritmos para pagamento usando cartão de crédito/débito ou através do PayPal. CreditCardStrategy.java

package com.journaldev.design.strategy;

public class CreditCardStrategy implements PaymentStrategy {

	private String name;
	private String cardNumber;
	private String cvv;
	private String dateOfExpiry;
	
	public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate){
		this.name=nm;
		this.cardNumber=ccNum;
		this.cvv=cvv;
		this.dateOfExpiry=expiryDate;
	}
	@Override
	public void pay(int amount) {
		System.out.println(amount +" paid with credit/debit card");
	}

}

PaypalStrategy.java

package com.journaldev.design.strategy;

public class PaypalStrategy implements PaymentStrategy {

	private String emailId;
	private String password;
	
	public PaypalStrategy(String email, String pwd){
		this.emailId=email;
		this.password=pwd;
	}
	
	@Override
	public void pay(int amount) {
		System.out.println(amount + " paid using Paypal.");
	}

}

Agora os nossos algoritmos de exemplo do padrão de estratégia estão prontos. Podemos implementar o Carrinho de Compras e o método de pagamento irá requerer entrada como estratégia de pagamento. Item.java

package com.journaldev.design.strategy;

public class Item {

	private String upcCode;
	private int price;
	
	public Item(String upc, int cost){
		this.upcCode=upc;
		this.price=cost;
	}

	public String getUpcCode() {
		return upcCode;
	}

	public int getPrice() {
		return price;
	}
	
}

ShoppingCart.java

package com.journaldev.design.strategy;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class ShoppingCart {

	//Lista de itens
	List items;
	
	public ShoppingCart(){
		this.items=new ArrayList();
	}
	
	public void addItem(Item item){
		this.items.add(item);
	}
	
	public void removeItem(Item item){
		this.items.remove(item);
	}
	
	public int calculateTotal(){
		int sum = 0;
		for(Item item : items){
			sum += item.getPrice();
		}
		return sum;
	}
	
	public void pay(PaymentStrategy paymentMethod){
		int amount = calculateTotal();
		paymentMethod.pay(amount);
	}
}

Observe que o método de pagamento do carrinho de compras requer o algoritmo de pagamento como argumento e não o armazena em nenhum lugar como variável de instância. Vamos testar nossa configuração de exemplo do padrão de estratégia com um programa simples. ShoppingCartTest.java

package com.journaldev.design.strategy;

public class ShoppingCartTest {

	public static void main(String[] args) {
		ShoppingCart cart = new ShoppingCart();
		
		Item item1 = new Item("1234",10);
		Item item2 = new Item("5678",40);
		
		cart.addItem(item1);
		cart.addItem(item2);
		
		//pagar com paypal
		cart.pay(new PaypalStrategy("[email protected]", "mypwd"));
		
		//pagar com cartão de crédito
		cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));
	}

}

A saída do programa acima é:

50 paid using Paypal.
50 paid with credit/debit card

Diagrama de Classe do Padrão de Design de Estratégia

Pontos Importantes do Padrão de Design de Estratégia

  • Poderíamos ter usado composição para criar uma variável de instância para as estratégias, mas devemos evitar isso, já que queremos que a estratégia específica seja aplicada para uma tarefa particular. O mesmo é seguido nos métodos Collections.sort() e Arrays.sort() que recebem um comparador como argumento.
  • O padrão de estratégia é muito semelhante ao Padrão de Estado. Uma das diferenças é que o Contexto contém o estado como variável de instância e pode haver várias tarefas cuja implementação pode depender do estado, enquanto no padrão de estratégia a estratégia é passada como argumento para o método e o objeto de contexto não tem nenhuma variável para armazená-la.
  • O padrão de estratégia é útil quando temos vários algoritmos para uma tarefa específica e queremos que nossa aplicação seja flexível para escolher qualquer um dos algoritmos em tempo de execução para a tarefa específica.

Isso é tudo para o Padrão de Estratégia em Java, espero que tenha gostado.

Source:
https://www.digitalocean.com/community/tutorials/strategy-design-pattern-in-java-example-tutorial