Como Implementar Design Patterns em TypeScript: Strategy
O que é o Design Pattern Strategy?
O Design Pattern Strategy é um Design Pattern Comportamental que permite definir uma família de algoritmos ou estratégias, encapsular cada um como uma classe separada e torná-los intercambiáveis. Ele permite que o cliente selecione e use dinamicamente diferentes algoritmos em tempo de execução sem modificar o código do cliente.
Os principais participantes do padrão Strategy são:
Contexto: A classe que interage com os objetos de estratégia. Ele mantém uma referência a um objeto Strategy e delega o trabalho para a estratégia quando necessário.
Strategy: A interface ou classe abstrata que declara o(s) método(s) a ser(em) implementado(s) por estratégias concretas. Ele define uma interface comum para todas as estratégias, garantindo que elas tenham um comportamento consistente.
Estratégias Concretas: As classes que implementam a interface Strategy. Cada estratégia encapsula um algoritmo ou comportamento específico.
As principais vantagens de usar o padrão Strategy são:
Flexibilidade: O padrão Strategy permite adicionar, remover ou modificar estratégias de forma independente sem afetar o código do cliente. Promove fácil extensibilidade e adaptabilidade.
Encapsulamento: Cada estratégia é encapsulada em sua própria classe, o que aprimora a organização e a manutenção do código. Cada estratégia pode ser desenvolvida, testada e modificada independentemente.
Reutilização: As estratégias podem ser reutilizadas em diferentes contextos ou aplicações, promovendo a reutilização de código e reduzindo a duplicação.
Seleção em tempo de execução: O padrão Strategy permite a seleção de uma estratégia em tempo de execução, dando ao cliente a flexibilidade de escolher o algoritmo apropriado dinamicamente com base em diferentes condições ou preferências do usuário.
No geral, o padrão Strategy ajuda a gerenciar diferentes algoritmos ou estratégias de forma eficaz, fornecendo uma solução limpa e sustentável quando você tem uma família de algoritmos ou comportamentos intercambiáveis em seu projeto.
Como Implementar o Strategy
O padrão Strategy permite definir uma família de algoritmos, encapsular cada um como uma classe separada e torná-los intercambiáveis. Dessa forma, você pode alternar entre algoritmos ou estratégias em tempo de execução sem afetar o código do cliente. Vejamos como isso pode ser implementado:
1- Defina a interface Strategy: Crie uma interface chamada PaymentStrategy
que declare um método para realizar o pagamento, como por exemplo pay()
.
abstract class PaymentStrategy {
abstract pay(amount: number): void;
}
2- Implementar as estratégias concretas: Criar classes que implementem a interface PaymentStrategy
para cada método de pagamento. Por exemplo, você pode ter classes como CreditCardPaymentStrategy
, PayPalPaymentStrategy
e BankTransferPaymentStrategy
. Cada classe fornecerá sua própria implementação do método pay()
.
class CreditCardPaymentStrategy extends PaymentStrategy {
pay(amount: number): void {
// Implement credit card payment logic here
console.log(`Paying $${amount} using credit card.`);
}
}
class PayPalPaymentStrategy extends PaymentStrategy {
pay(amount: number): void {
// Implement PayPal payment logic here
console.log(`Paying $${amount} using PayPal.`);
}
}
class BankTransferPaymentStrategy extends PaymentStrategy {
pay(amount: number): void {
// Implement bank transfer payment logic here
console.log(`Paying $${amount} using bank transfer.`);
}
}
3- Implemente o contexto: Crie uma classe chamada Order
que represente um pedido na aplicação de e-commerce. A classe Order
terá uma referência à interface PaymentStrategy
, permitindo que o cliente configure a forma de pagamento dinamicamente.
class Order {
private paymentStrategy: PaymentStrategy;
constructor(paymentStrategy: PaymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
setPaymentStrategy(paymentStrategy: PaymentStrategy): void {
this.paymentStrategy = paymentStrategy;
}
processOrder(amount: number): void {
// Process the order logic
// Call the payment strategy
this.paymentStrategy.pay(amount);
// Other order processing steps
}
}
4- Agora, quando um usuário fizer um pedido, você pode definir dinamicamente o método de pagamento usando o método setPaymentStrategy()
da classe Order
. O pagamento será processado com base na estratégia selecionada.
Aqui está um exemplo de como o padrão Strategy pode ser usado:
const order = new Order(new PayPalPaymentStrategy());
// Set the payment strategy based on user's choice
const paymentStrategy = new CreditCardPaymentStrategy(); // Or any other strategy
order.setPaymentStrategy(paymentStrategy);
// Process the order
order.processOrder(100.0);
Ao utilizar o padrão Strategy, você pode estender facilmente o sistema de pagamento com novos métodos de pagamento sem modificar o código existente. Ele promove flexibilidade, capacidade de manutenção e separação de preocupações em seu projeto.