Potencialize a Modularidade no NestJS com o Padrão Strategy
O desenvolvimento de aplicativos e serviços robustos requer o uso de padrões de projeto eficientes. Neste artigo, vamos explorar a aplicação do padrão Strategy em conjunto com o framework NestJS. Veremos como esse padrão pode melhorar a modularidade e a flexibilidade de um aplicativo NestJS, permitindo a fácil adição e substituição de estratégias de negócio.
O que é o Strategy Pattern?
O Strategy Pattern, ou Padrão Estratégia, é um dos padrões de projeto definidos pelo Gang of Four (GoF). Ele permite encapsular diferentes algoritmos ou comportamentos em classes separadas, conhecidas como estratégias, e selecionar dinamicamente qual estratégia usar em tempo de execução. Isso facilita a troca de algoritmos sem a necessidade de alterar o código que os utiliza, promovendo uma maior flexibilidade e extensibilidade no design do software.
Em outras palavras, é um padrão de projeto comportamental que permite a definição de uma família de algoritmos encapsulados em classes separadas. Cada classe representa uma estratégia específica que pode ser selecionada e utilizada dinamicamente em tempo de execução. Essa abordagem facilita a adição de novas estratégias e a alteração das existentes sem a necessidade de modificar o código existente.
Benefícios do Strategy Pattern:
- Modularidade: Ao separar as estratégias em classes independentes, o Strategy Pattern promove a modularidade do código. Cada estratégia é responsável por uma única tarefa e pode ser desenvolvida e testada separadamente.
- Flexibilidade: Com o Strategy Pattern, é possível trocar a estratégia em tempo de execução, sem impactar outras partes do sistema. Isso permite adaptar o comportamento do aplicativo de acordo com as necessidades específicas do momento.
- Reutilização de código: As classes de estratégia podem ser reutilizadas em diferentes contextos, facilitando o desenvolvimento e evitando duplicação de código.
- Testabilidade: Como as estratégias são encapsuladas em classes independentes, é mais fácil escrever testes unitários para cada estratégia, garantindo a qualidade do código.
Aplicando o Strategy Pattern no NestJS:
Ao desenvolver uma API com o NestJS, frequentemente nos deparamos com a necessidade de implementar diferentes estratégias para realizar uma determinada tarefa, como por exemplo, processar um pedido de pagamento. Utilizando o Strategy Pattern, podemos definir uma interface comum para essas estratégias e criar classes separadas para cada implementação específica. Vamos ver um exemplo prático:
Passo 1: Definindo a interface do Strategy
Primeiramente, precisamos criar uma interface que represente o contrato para todas as estratégias. Por exemplo, podemos criar uma interface chamada “PaymentStrategy” com um método chamado “processPayment”.
// payment.strategy.ts
export interface PaymentStrategy {
execute(amount: number): Promise<void>;
}Passo 2: Implementando as estratégias
Agora, podemos criar diferentes classes que implementam a interface “PaymentStrategy” de acordo com as necessidades do nosso sistema. Cada classe concreta será responsável por implementar a lógica específica para processar o pagamento.
// credit-card.strategy.ts
export class CreditCardStrategy implements PaymentStrategy {
async execute(amount: number): Promise<void> {
// Implementação específica para pagamento com cartão de crédito
}
}
// paypal.strategy.ts
export class PayPalStrategy implements PaymentStrategy {
async execute(amount: number): Promise<void> {
// Implementação específica para pagamento com PayPal
}
}Passo 3: Utilizando as estratégias no NestJS
Agora que temos nossas estratégias implementadas, podemos utilizá-las no contexto do NestJS. Podemos injetar a interface “PaymentStrategy” em um serviço e selecionar a estratégia apropriada com base em certas condições ou preferências do usuário.
// payment.service.ts
@Injectable()
export class PaymentService {
constructor(
@Inject('PaymentStrategy')
private readonly paymentStrategy: PaymentStrategy,
) {}
async processPayment(amount: number): Promise<void> {
// Lógica de negócio antes do processamento do pagamento
await this.paymentStrategy.execute(amount);
// Lógica de negócio após o processamento do pagamento
}
}Passo 4: Configurando a injeção de dependência no módulo
Para garantir que o NestJS saiba qual estratégia utilizar, devemos configurar a injeção de dependência no módulo correspondente. Podemos usar o recurso de provedores personalizados do NestJS para vincular uma estratégia específica à interface “PaymentStrategy”.
// payment.module.ts
@Module({
providers: [
{
provide: 'PaymentStrategy',
useClass: CreditCardStrategy, // Ou PayPalStrategy
},
PaymentService,
],
})
export class PaymentModule {}Conclusão
O Strategy Pattern é uma ferramenta poderosa para melhorar a modularidade e a flexibilidade de aplicativos NestJS. Ao separar algoritmos em classes independentes, podemos adicionar, substituir e combinar estratégias facilmente. Isso resulta em um código mais organizado, reutilizável e de fácil manutenção. Ao utilizar o Strategy Pattern em conjunto com o NestJS, podemos construir aplicativos mais robustos e escaláveis, adaptados às necessidades do negócio.
Para ler em Inglês:
