6. Perceba que
O plugue e a tomada possuem interfaces diferentes entre si,
portanto eles não podem se encaixar.
Porém
Utilizando um ADAPTADOR, um instrumento que transforma
uma interface em outra, a conexão foi realizada.
7.
8. Por que não troquei a tomada?
Por que não troquei o plugue do
dispositivo?
9. Em Projetos de Desenvolvimento de
Software também encontramos
problemas como este!
10. Um exemplo
Suponha que em um projeto, utilizamos uma classe utilitária
de um framework (ou o próprio completo) ou de uma
biblioteca de classes de terceiros.
Em todo o nosso projeto, utilizamos os métodos desta
classe.
11. Classe de uma biblioteca de
terceiros utilizada no projeto
class ClasseUtil
def hello
"Hello"
end
def world
"World"
end
end
12. Na documentação da classe, o método hello será
depreciado (sem utilização) no futuro.
Digamos que versões subseqüentes da classe sejam lançadas
e o método hello tenha sido retirado definitivamente.
13. Como poderemos utilizar a nova versão da classe em nossa
aplicação que utiliza o antigo método hello (agora
excluído)?
Se apenas substituírmos a classe em nossa aplicação, será
disparado um erro, afirmando que está sendo feito uma
chamada que não existe. E agora?
15. Propósito
O principal objetivo do Adapter é facilitar a conversão da
interface de uma classe para outra interface mais
interessante para o cliente, fazendo com que várias classes
possam trabalhar em conjunto independentemente das
interfaces originais. Às vezes é preciso modificar uma
classe que não pode ser alterada adequadamente devido à
falta do código fonte (alguma biblioteca de classes
comercial), ou por alguma outra razão. O Adapter é uma das
formas de modificar classes nestas circunstâncias, sendo
classificado com a de finalidade estrutural e abrange tanto
escopo de classe quanto de objeto.
16. Motivação:
Adapter é usado quando:
Uma classe já existente e sua interface não combinam
com a esperada pelo cliente;
Se quer criar uma classe reutilizável que coopera com
classes não relacionadas ou não previstas, isto é, classes
que não necessariamente tenham interfaces compatíveis;
Se necessita usar várias subclasses existentes, mas é
impraticável adaptar suas interfaces fazendo um
Subclassing de cada uma.
17. Formas de Implementação
Object Adapter
Cria-se uma classe intermediária que servirá como
interface entre as chamadas do código do cliente e o
código alvo.
Class Adapter
Cria-se uma classe que herdará da classe do cliente e
sobrescreve-se ou recria-se o método chamado.
18. Componentes
Adaptado: Classe que contém a funcionalidade que o
cliente está interessado. Entretanto não é compatível
com o cliente.
Alvo: Domínio da interface específica que o cliente usa.
Adaptador: Classe que adapta o Alvo ao Adaptado.
Cliente: Interage com o Adaptado incompatível.
19. Object Adapter
Objects usam uma técnica composta para adaptar uma
interface à outra. O Adapter herda a interface-alvo que
o client eespera ver. Quando o cliente chama um método
no objeto alvo, o pedido é traduzido para o método
correspondente no adaptado.
ObjectAdapters permitem que o cliente e o adaptado
sejam transparentes um para o outro. Só o Adapter sabe
da existencia dos dois.
Sua principal vantagem é que o Adapter adapta não
somente o Adaptado mas todas as suas subclasses. A
principal desvantagem é que seu uso requer a escrita de
todo o código necessario para delegar as chamadas do
Adaptado.
21. Class Adapter
Class Adapters usam herança invés de composição. Isso
significa que invés de elegaras chamadas ao Adaptado,
ela as põe em sub-classes. Assim, Class Adapters devem
herdar tanto o Alvo quanto o Adaptado.
Ao fazer uma chamada ao Alvo, a chamada é
simplesmente encaminhada para o método especifico que
foi herdado pela interface
23. Object Adapters X Class Adapters
O OA permite que um único Adapter trabalhe com muitos
Adaptados (e suas sub-classes), já o CA adapta uma
classe concreta e não suas sub-classes.
O CA pode sobrepor alguns comportamentos do Adaptado
visto que é uma subclasses dele, o que não é tão trivial no
OA.
A implementação do CA normalmente é mais simples pois
envolve menos código.
24. Aplicabilidade
Use o Padrão Adapter quando:
Desejar usar uma classe existente e sua interface não
corresponde ao que você precisa;
Desejar criar uma classe reutilizável que coopera com
classes imprevistas ou não relacionáveis, isto é, classes
que não tem necessariamente interfaces compatíveis.
27. A Nova Classe da Biblioteca
class ClasseUtil
#def hello ----------> Método depreciado
# "Hello"
#end
def alo
"Hello"
end
def world
"World"
end
end
28. Adaptador (Composição)
class AdapterC
@biblioteca
def initialize
self.biblioteca = ClasseUtil.new #instanciando a biblioteca
end
def hello
self.biblioteca.alo
end
def world
self.biblioteca.world
end
end
29. Adaptador (Herança)
class AdapterH < ClasseUtil
def initialize
end
def hello
self.alo #readaptando a chamada para o metodo correto
end
end
31. Mysql, Postgres, Oracle, SqlServer...
results = mysql_connection.query(sql)
ou
results = sybase_connection.sql(sql)
e por aí vai...
32. Active Record soluciona com
AbstractAdapter
define a interface para um banco de dados que é usado
em todo o Active Record
Subclasses da AbstractAdapter: MysqlAdapter,
SybaseAdapter, OracleAdapter, etc.
Cada subclasse implementa seus métodos
34. Procure modificar as classes quando:
as alterações forem simples e claras;
você entende completamente o código contido na classe;
a modificação será "definitiva" para o projeto
LEMBRETE: O Ruby suporta
modificar o objeto em tempo
de execução
35. Adote a solução de adaptadores
quando:
a incompatibilidade entre as interfaces é grande e
complexa ;
você não tem bastante conhecimento e afinidade com o
código e a idéia contida na classe
36. Por que não troquei a tomada?
Por que não troquei o plugue do
dispositivo?
37. Padrões Relacionados
O Adapter se relaciona a outro padrões pela semelhança
entre a implementação.
Proxy: Enquanto o Adapter visa traduzir interfaces
entre cliente e objeto final, o Proxy visa poder interferir
entre a chama do Cliente e a execucao do objeto final.
Decorator: Agrega funcionalidades a outros objetos sem
alterar sua interface. Por isso esse padrão é mais
transparente à aplicação que uma Adapter. Como sua
interface se mantém, o Decorator suporta composição
recursiva, algo que nao se aplica ao Adapter.
Bidge: Tem uma estrutura similiar ao Adapter, mas o
proposito de separar a interface da implementação.