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.