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: