Buscar

[aula6] Adapter_facade

Prévia do material em texto

Programação Avançada
Prof. Anderson B. Pinheiro
2019.1
Padrões de Projeto
Estruturais
Padrões Estruturais
 As interações entre os objetos de um sistema podem 
gerar fortes dependências
 Aumentando a complexidade de eventuais alterações do 
sistema
 Custo de manutenção aumenta
 Padrões estruturais buscam reduzir o acoplamento entre 
os objetos
Padrões Estruturais 
 Adapter – Permitir que um objeto seja substituído por outro 
que, apesar de realizar a mesma tarefa, possui uma interface 
diferente.
 Bridge – Separar uma abstração de sua representação, de 
forma que ambos possam variar e produzir tipos de objetos 
diferentes
 Composite – Agrupar objetos que fazem parte de uma relação 
parte-todo de forma a tratá-los sem distinção
 Decorator – Adicionar funcionalidades a um objeto 
dinamicamente
Padrões Estruturais
 Facade – Prover uma interface simplificada para a utilização de 
várias interfaces de um subsistema
 Front Controller – Centralizar todas as requisições a uma 
aplicação web
 Flyweight – Compartilhar, de forma eficiente, objetos que são 
usados em grande quantidade
 Proxy – Controlar as chamadas a um objeto através de outro 
objeto de mesma interface
Adapter
 O padrão Adapter é utilizado quando 
necessário ligar uma nova biblioteca de 
classes a um sistema já existente
 Em geral, com interfaces diferentes
 A solução é criar uma classe que funcione como um 
adaptador
 Adaptando a interface do novo fornecedor ao formato que 
o sistema já conhece
 Compatibilizando um sistema a diferentes frameworks ou 
APIs que possam vir a ser implementadas
 Alvo: define a interface específica do domínio da aplicação
 Adaptado: define uma interface existente que precisa ser adaptada
 Adaptador: adapta a interface do Adaptado à interface de Alvo
public class Tomada3Pinos{ 
public void ligarTomada3Pinos(){
System.out.println(“Tomada de 3 ligada”)
}
}
public class Cliente {
public static void main(String args[]) {
Tomada3Pinos tomada = new Tomada3Pinos();
t3.ligarTomada3pinos();
}
}
public class Tomada2Pinos{ 
public void ligarTomada2Pinos(){
System.out.println(“Tomada de 2 ligada”)
}
}
Nova classe que precisa ser adaptada ao sistema.
Alvo
public class Tomada3Pinos{ 
public void ligarTomada3Pinos(){
System.out.println(“Tomada de 3 ligada”)
}
}
public class Tomada2Pinos{ 
public void ligarTomada2Pinos(){
System.out.println(“Tomada de 3 ligada”)
}
}
Adaptado
public class Tomada2PinosAdapter extends Tomada3Pinos {
private Tomado2Pinos t2Pinos;
public Tomado2PinosAdapter(Tomada2Pinos t2Pinos) {
this.t2Pinos = t2Pinos;
}
public void ligarTomada3Pinos() {
t2Pinos.ligarTomada2Pinos(); 
}
}
public class Teste {
public static void main(String args[]) {
Tomada2PinosAdapter t2 = 
new Tomada2PinosAdapter(new Tomada2Pinos());
t2.ligarTomada3pinos();
}
}
 Exemplo 2:
Imaginem que a aplicação do cliente possui uma classe 
(PrintRelatorio) para impressão de relatórios;
 implementada inicialmente para impressão somente 
no console;
 Possui um objeto do tipo PrintStream chamado out;
 Possui um método chamado imprime que recebe a 
string a ser impressa.
public class PrintRelatorio {
private PrintStream out;
public PrintStream getOut(){
return this.out;
}
public void setOut(PrintStream out) {
this.out = out;
}
public void imprime(String texto){
getOut().print (texto);
}
}
Utilizando a classe PrintRelatorio
public static void main(String[] args) {
PrintRelatorio relatorio = new PrintRelatorio();
relatorio.setOut(System.out);
relatorio.imprime("texto");
}
 O problema é que agora o cliente precisa de uma 
impressão mais elaborada em uma caixa de mensagens 
(JOptionPane);
 A classe PrintRelatorio já esta homologada em 
execução;
 Precisamos usar JOptionPane.showMessageDialog() no 
lugar de System.out.print ();
 E ainda é necessário chamar 
relatorio.setOut(JOptionPane), mas esse método 
recebe algo do tipo PrintStream;
 Como contornar esse conjunto de problemas?
 Criamos uma nova classe AdaptadoraParaPainel:
 Estendemos PrintStream;
 Somos então obrigados a inserir um construtor para 
informar um Arquivo, visto que a especialidade dela é 
trabalhar com streams. 
 Mas não vamos trabalhar com arquivos! 
 Então inserimos o construtor que ela espera, declarar 
a exceção que ela espera, apenas para compilador 
parar de reclamar.
public class AdaptadoraParaPainel extends 
PrintStream{
public AdaptadoraParaPainel() throws
FileNotFoundException{
super(new File(“”));
}
@overhide
public void print(String texto){
JOptionPane.showMessageDialog(null,texto);
}
}
 Assim a classe cliente continua invocando o método setOut() que 
espera um PrintStream:
public class Cliente {
public static void main(String[] args) throws
FileNotFoundException {
PrintRelatorio relatorio = new PrintRelatorio();
relatorio.setOut(new AdaptadoraParaPainel());
relatorio.imprime("texto");
}
}
 Quando queremos usar uma classe já pronta, mas que possui uma 
interface diferente da que precisamos;
 Como exemplos no próprio Java temos:
Classes envoltório:
 Integer
 Boolean
 Float
 Adaptadores de evento(AWT/SWING)
 Java.awt.MouseAdapter adapta java.awt.MouseListener a uma 
interface mais simples
Facade
 Objetivo: Ocultar a complexidade de uma 
ou mais classes através de uma 
“fachada”:
 Simplificar a utilização de um 
subsistema
 Encapsular as interfaces, fornecendo 
uma simplificada para acessar as 
principais funcionalidades do 
subsistema
 Problema: Considere que que em um sistema existem várias 
classes, as quais possuem diversos métodos:
 As principais funcionalidades do sistema provêm de alguns 
métodos dessas classes
 A comunicação do sistema com as várias classes gera alto 
acoplamento
Solução: Criar uma classe (“fachada”) que mantém a interação 
com o subsistema de classes, e fornece uma interface mais 
simples para o sistema
 Essa seria uma interface de mais alto nível
 Considere: Sistema multimídia
 Sistema de vídeo (SistemaDeVideo)
 configurarResolucao
 configurarCores
 renderizarImagem
 Sistema de áudio (SistemaDeAudio)
 configurarFrequencia
 configurarVolume
 configurarCanais
 reproduzirAudio
 Sistema de entrada de dados (SistemaDeInput)
 configurarTeclado
 configurarJoystick
 lerInput
 Resumo:
 Simplifica uma interface unificando um conjunto de classes 
mais complexas que fazem parte de um subsistema
 Permite desconectar a implementação do sistema principal 
de qualquer subsistema de classes
 Um sistema pode ter várias “fachadas” integradas
 Versus Adapter:
 O padrão Adapter tem por objetivo alterar uma interface para 
torná-la compatível com o sistema (Converter)
 O padrão Facade visa fornecer uma interface unificada/simplificada 
para um subsistema (Unificar)

Continue navegando