Codificando -se em um canto

Vejamos um exemplo. Construir um aplicativo de comércio eletrônico é bastante comum. Seja um site on-line ou um sistema físico de ponto de venda, o aplicativo precisará processar cartões de crédito. Agora, o processamento do cartão de crédito é uma coisa bastante complexa, mas é algo que se presta a abstrações.

Digamos que seu sistema use o processador de pagamento do PaySfff. Se você é um aderente rigoroso ao princípio de Yagni (que eu não recomendaria), você apenas seguirá em frente e coda-se com a implementação do Paystuff como assim:


class PayStuffPaymentProcessor {
  processPayment(amount: number) {
    console.log(`Processing $${amount} payment via PayStuff...`);
  }
}

class Checkout {
  private paymentProcessor: PayStuffPaymentProcessor;

  constructor() {
    this.paymentProcessor = new PayStuffPaymentProcessor();
  }

  processOrder(amount: number) {
    this.paymentProcessor.processPayment(amount);
    console.log("Order processed successfully!");
  }
}

// Usage
const checkout = new Checkout();
checkout.processOrder(100);
checkout.processOrder(50);

Isso funciona bem, eu acho. Você pode processar e coletar dinheiro para pedidos e tudo está bem. Não é mutável. E não importa que você não possa testá -lo. Mas ei, você não vai precisar de nada mais, certo? Yagni para a vitória!

Mas opa! Paystuff sai do negócio! Você precisa começar a usar o processador Connectbucks em vez do Paystuff. E no mesmo dia em que você percebe que seu gerente de produto pede que você adicione suporte para pagar com o PayPal e o Google Pay. De repente, seu sistema não é apenas difícil de testar, mas nem funciona mais, e fornecer toda essa nova funcionalidade exigirá uma cirurgia bastante importante para o seu sistema, certo?

A abstração salva o dia

O que você deveria ter feito é perceber que você precisará de uma abstração. Assim, você cria uma interface e escreve todo o seu código contra ele e não uma implementação específica. Então, em vez de criar a implementação no local, você adia a decisão de implementação e “injete” no construtor a implementação da abstração que deseja usar.