Buscar

Adapter, facade, bridge, singleton e composite

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 5 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Portanto, o adaptador é um intermediador que recebe solicitações do cliente e converte essas solicitações num formato que o fornecedor entenda. O adaptador converte uma interface para outra, porém, também poderíamos ter um caso em que precisaríamos adaptar mais de uma classe, nesse caso entra em cena outro padrão de projeto chamado Facade (Fachada) que é discutido em outro artigo. Se a interface do fornecedor mudar novamente apenas o Adaptador necessitará ser modificado sem alterar o resto do sistema.
A definição oficial do padrão Adapter é: “O Padrão Adapter converte uma interface de uma classe para outra interface que o cliente espera encontrar. O Adaptador permite que classes com interfaces incompatíveis trabalhem juntas”.
Segue abaixo um exemplo de implementação em Java utilizando o Padrão Adapter.
Listagem 1: Exemplo de implementação do Padrão Adapter
public class TomadaDeDoisPinos {
	public void ligarNaTomadaDeDoisPinos() {
		System.out.println("Ligado na Tomada de Dois Pinos");
	}
}
public class TomadaDeTresPinos {
	public void ligarNaTomadaDeTresPinos() {
		System.out.println("Ligado na Tomada de Tres Pinos");
	}
}
public class AdapterTomada extends TomadaDeDoisPinos {
	private TomadaDeTresPinos tomadaDeTresPinos;
	public AdapterTomada(TomadaDeTresPinos tomadaDeTresPinos) {
		this.tomadaDeTresPinos = tomadaDeTresPinos;
	}
	public void ligarNaTomadaDeDoisPinos() {
		tomadaDeTresPinos.ligarNaTomadaDeTresPinos();
	}
}
Veja que nós temos uma classe TomadaDeDoisPinos mas nós queremos nos conectar a uma classe TomadaDeTresPinos que possui outros métodos e uma outra interface diferente. Assim criamos um Adapter para que possamos acessá-la. Veja que o Adaptador herda da classe que você possui (o seu Target como mostrado no diagrama de classes). Dentro do adaptador temos o que o cliente precisa que é o TomadaDeTresPinos que será chamado posteriormente no método ligarNaTomadaDeDoisPinos que na verdade está chamando o método ligarNaTomadaDeTresPinos do novo fornecedor.Para executarmos o aplicativo de teste podemos usar a implementação abaixo:
Listagem 2: Exemplo de execução do padrão adapter
public class Teste {
	public static void main(String args[]) {
		TomadaDeTresPinos t3 = new TomadaDeTresPinos();
		AdapterTomada a = new AdapterTomada(t3);
		a.ligarNaTomadaDeDoisPinos();
	}
}
Nota-se que o cliente faz uma chamada normalmente usando a tomada de dois pinos, mas na realidade esta chamada está sendo adaptada para uma tomada de três pinos. Assim temos duas interfaces que não eram compatíveis entre si conversando normalmente.
FACADE
O Padrão de Projeto Facade oculta toda a complexidade de uma ou mais classes através de uma Facade (Fachada). A intenção desse Padrão de Projeto é simplificar uma interface. Existem outros dois Padrões de Projetos (Decorator e Adapter) já discutidos em outros artigos que possuem similaridades com o Padrão Facade, porém existem diferenças em relação a este padrão, como será visto mais adiante.
Segue abaixo um exemplo de implementação em Java utilizando o Padrão Facade.
Listagem 1: Exemplo de implementação do Padrão Facade
public class Cpu {
	public void start() {
		System.out.println("inicialização inicial");
	}
	public void execute() {
		System.out.println("executa algo no processador");
	}
	public void load() {
		System.out.println("carrega registrador");
	}
	public void free() {
		System.out.println("libera registradores");
	}
}
public class Memoria {
	public void load(int position, String info) {
		System.out.println("carrega dados na memória");
	}
	public void free(int position, String info) {
		System.out.println("libera dados da memória");
	}
}
public class HardDrive {
	public void read(int startPosition, int size) {
		System.out.println("lê dados do HD");
	}
	public void write(int position, String info) {
		System.out.println("escreve dados no HD");
	}
}
public class ComputadorFacade {
	private Cpu cpu = null;
	private Memoria memoria = null;
	private HardDrive hardDrive = null;
	public ComputadorFacade(Cpu cpu,
					Memoria memoria,
					HardDrive hardDrive) {
		this.cpu = cpu;
		this.memoria = memoria;
		this.hardDrive = hardDrive;
	}
	public void ligarComputador() {
		cpu.start();
		String hdBootInfo = hardDrive.read(BOOT_SECTOR, SECTOR_SIZE);
		memoria.load(BOOT_ADDRESS, hdBootInfo);
		cpu.execute();
		memoria.free(BOOT_ADDRESS, hdBootInfo);
	}
}
No exemplo acima podemos notar a quantidade de classes e métodos envolvidos quando precisamos inicializar o computador. Toda essa complexidade é exposta ao cliente que poderia chamar todas essas classes e cada um dos métodos das classes para realizar a tarefa de inicializar o computador. No entanto, ao usar uma Facade encapsulamos essa complexidade oferecendo uma interface simples e unificada ao cliente evitando acoplamento e complexidade. Apenas chamando o método ligarComputador() da classe ComputadorFacade tem-se uma interface simples que diz o que ela faz exatamente, sem expor a complexidade envolvida na operação.
Nota-se que todas as chamadas que estão no Facade poderiam ser feitas uma a uma no cliente, porém isso gera muito acoplamento e complexidade para o cliente, por isso a Facade simplifica e unifica esse conjunto de classes que gera muita complexidade.
Composite
Nome e Classificação do Padrão: Composite - Padrão Estrutural
Intenção e Objetivo: O padrão Composite é utilizado quando queremos reutilizar método e funções de algum objeto e colocar em qualquer outro, sendo vários objetos ligados a um único.
Motivação: Em certas estruturas necessitamos por muitas vezes de métodos e funções que já estão especificadas em um determinado objeto, sendo necessário apenas a ligação entre os dois para assim poder ser reutilizado o código.
Aplicabilidade: Este padrão pode ser usado sempre que desejarmos construir objetos exisitindo objetos do mesmo tipo.
Estrutura:
Estrutura do Composite
Participantes:Componente:* Declara a interface para objetos na  composição* Implementa comportamento default para  interface comum a todas as classes, como apropriado; * Declara uma interface para acessar ou gerenciar seus * Componentes filhos;
Folha: *Representa objetos folhas na composição. Uma folha não tem filhos; *Define comportamento para objetos  primitivos na composição.
Composição: * Define comportamento para Componentes que têm filhos;* Armazena Componentes filhos; * Implementa operações relacionadas com filhos na interface do Componente.
 Cliente:*Manipula objetos na composição através da interface Componente.
Consequências: Com o uso do padrão Composite podemos criar objetos com uma grande complexidade e eles serem compostos por outros objetos menores, além de deixar o código bem estruturado e de fácil entendimento, sendo rápida a forma de adicionar novos componentes, métodos e funções.
Implementação
Referências explícitas aos pais;
Compartilhamento de componentes;
Maximização da interface de componentes;
Declaração as operações de gerência de filhos.
Exemplo de Código:
public abstract class CamisetaComponent {
 String marcaDaCamiseta;
 public void printNomeDaCamiseta() {
 System.out.println(this.marcaDaCamiseta);
 }
 public String getNomeDaCamiseta() {
 return this.marcaDaCamiseta;
 }
 public void adicionar(CamisetaComponent novaCamiseta) throws Exception {
 throw new Exception("erro");
 }
 public void remover(String marcaDaCamiseta) throws Exception {
 throw new Exception("Erro");
 public CamisetaComponent getCamiseta(String marcaDacamiseta) throws Exception {
 throw new Exception("Erro);
 }
}
package testecomposite;
public class CamisetaRegata extends CamisetaComponent {
 
public CamisetaRegata(String marcaDaCamiseta) {
 this.marcaDaCamiseta = marcaDaCamiseta;
 }
}
package testecomposite;
import java.util.ArrayList;
/**
 *
 * @author Pauta
 */
public class RoupaComposite extends CamisetaComponent {
 ArrayList<CamisetaComponent> camisetas= new ArrayList<CamisetaComponent>();
 public RoupaComposite(String marcaDaCamiseta) {
 this.marcaDaCamiseta = marcaDaCamiseta;
 }
 
 public void printNomeDoArquivo() {
 System.out.println(this.marcaDaCamiseta);
 for (CamisetaComponent arquivoTmp : camisetas) {
 arquivoTmp.printNomeDaCamiseta();
 }
 }
 @Override
 public void adicionar(CamisetaComponent novaCamiseta) {
 this.camisetas.add(novaCamiseta);
 }
 @Override
 public void remover(String nomeDaCamiseta) throws Exception {
 for (CamisetaComponent arquivoTmp : camisetas) {
 if (arquivoTmp.getNomeDaCamiseta()== nomeDaCamiseta) {
 this.camisetas.remove(arquivoTmp);
 return;
 }
 }
 throw new Exception("Não existe este camiseta");
 } 
 public CamisetaComponent getCamiseta(String nomeDaCamiseta) throws Exception {
 for (CamisetaComponent arquivoTmp : camisetas) {
 if (arquivoTmp.getNomeDaCamiseta() == nomeDaCamiseta) {
 return arquivoTmp;
 }
 }
 throw new Exception("Não existe este camiseta");
 }
}
Singleton - Usado quando desejado, que uma classe tenha apenas uma instância na aplicação. Abaixo, mostra alguns aspectos que devem serem cuidados ao criar esse padrão.
O construtor da classe fica como privado (private), sendo que não pode ser instanciada para fora da própria classe.
A classe é final, pois não permite a criação de subclasses da própria classe.
O acesso é permitido através do método que retorna a instância única da classe, ou faz a criação de uma, caso não tenha sido criada.
Bridge - Esse padrão separa uma abstração de sua implementação, permitindo que ambas possam variar independente, sendo estabelecida uma ponte (tradução de “bridge”) entre elas.

Outros materiais