Padrão Adapter
Recentemente tenho me dedicado bastante a estudar sobre padrões de projetos - Design Patterns - e tenho visto alguns bem usuais, e então pretendo publicar uma série sobre esse tão discutido assunto.
Pois bem, como diz a definição Design Patterns segundo a Wikipedia:
"descrevem soluções para problemas recorrentes no desenvolvimento de sistemas de software orientados a objetos. Um padrão de projeto estabelece um nome e define o problema, a solução, quando aplicar esta solução e suas conseqüências."
Hoje falarei sobre o padrão "Adapter", que consiste no seguinte problema: Reutilizar Objetos incompatíveis.
Vou utilizar uma situação-problema real:
Imagine que em meu sistema eu tenha uma classe compra, que para fazer o pagamento,
utiliza o método Billing, e que esse método espera algo que herde de uma
interface IPagamento.
Cartão de crédito é uma classe abstrata que herda de IPagamento.
Boleto é uma classe que herda de IPagamento.
Visa e master são as implementações reais que utilizávamos, até então, para fazer o Billing dependendo do cartão que o cliente utilizava, e a propósito, elas herdam de CartaodeCredito. Segue o diagrama:
Porém, a loja decide que vai ter mais um tipo de cartão de crédito, terá o “Sorocred”.
O Analista logo pensa: “Tudo bem, é só eu herdar de
CartaodeCredito, implementar a forma específica de Billing e pronto! “.
Só que vem a surpresa: o cliente tem a própria Dll de Billing, que não pode ser alterada, ou pior: a estrutura de classe de “Sorocred” foi desenhada da seguinte maneira:
“E agora? A minha linguagem não permite herança múltipla! O que fazer?”
Com o padrão Adapter, é possível fazer essa implementação, e de forma simples, sem ter que mudar o código do cliente (Sorocred) e nem o meu.
Solução:
Criar uma classe adaptadora, que encapsule o método sorocred e herde de Cartão
de crédito.
No diagrama seria assim:
A classe “SorocredAdapter” teria algo como
Public String Billing()
{
return new Sorocred().BillingSorocred();
}
Com isso, eu não modifiquei o meu código, eu extendi algo existente, que seria até o princípio Aberto-fechado do SOLID, não modifiquei o lado do cliente, e fiz a implementação com o mínimo impacto possível.
O diagrama final: