Minha opinião sobre o assunto.
Todos os quatro padrões têm muito em comum, todos os quatro são chamados informalmente de invólucros ou padrões de invólucro. Todos usam composição, agrupando o assunto e delegando a execução ao assunto em algum momento, mapeando uma chamada de método para outra. Eles poupam ao cliente a necessidade de construir um objeto diferente e copiar todos os dados relevantes. Se usados com sabedoria, eles economizam memória e processador.
Ao promover o acoplamento flexível, eles tornam o código, uma vez estável, menos exposto a mudanças inevitáveis e mais legível para outros desenvolvedores.
Adaptador
O adaptador adapta o assunto (adaptado) a uma interface diferente. Dessa forma, podemos adicionar objetos a uma coleção de tipos nominalmente diferentes.
O adaptador expõe apenas métodos relevantes ao cliente, pode restringir todos os outros, revelando intenções de uso para contextos específicos, como adaptar a biblioteca externa, fazer com que pareça menos geral e mais focado nas necessidades de nossos aplicativos. Os adaptadores aumentam a legibilidade e a auto descrição de nosso código.
Os adaptadores protegem uma equipe do código volátil de outras equipes; uma ferramenta de salvador de vidas ao lidar com equipes offshore ;-)
O objetivo menos mencionado é impedir que a classe de assunto exceda as anotações. Com tantas estruturas baseadas em anotações, isso se torna um uso mais importante do que nunca.
O adaptador ajuda a contornar a limitação de Java de apenas uma herança. Ele pode combinar vários adaptados em um envelope, dando a impressão de herança múltipla.
Em termos de código, o adaptador é "fino". Ele não deve adicionar muito código à classe adaptee, além de simplesmente chamar o método adaptee e ocasionais conversões de dados necessárias para fazer essas chamadas.
Não há muitos bons exemplos de adaptadores no JDK ou nas bibliotecas básicas. Os desenvolvedores de aplicativos criam adaptadores para adaptar bibliotecas a interfaces específicas de aplicativos.
Decorador
O Decorator não apenas delega, não apenas mapeia um método para outro, mas também modifica o comportamento de alguns métodos de assunto, pode decidir não chamar o método de assunto, delegar para um objeto diferente, um objeto auxiliar.
Decoradores normalmente adicionam funcionalidade (transparente) a objetos quebrados, como log, criptografia, formatação ou compactação ao assunto. Essa nova funcionalidade pode trazer muitos códigos novos. Portanto, os decoradores geralmente são muito mais "gordos" que os adaptadores.
O decorador deve ser uma subclasse da interface do sujeito. Eles podem ser usados de forma transparente em vez de seus assuntos. Consulte BufferedOutputStream, ainda é OutputStream e pode ser usado como tal. Essa é uma grande diferença técnica dos adaptadores.
Exemplos de livros de texto de toda a família de decoradores estão prontamente no JDK - o Java IO. Todas as classes, como BufferedOutputStream , FilterOutputStream e ObjectOutputStream, são decoradoras de OutputStream . Eles podem ser em camadas de cebola, onde um decorador é decorado novamente, adicionando mais funcionalidade.
Proxy
O proxy não é um wrapper típico. O objeto agrupado, o assunto do proxy, ainda não pode existir no momento da criação do proxy. O proxy geralmente o cria internamente. Pode ser um objeto pesado criado sob demanda ou é um objeto remoto em JVM diferente ou em um nó de rede diferente e até mesmo um objeto não Java, um componente no código nativo. Ele não precisa envolver ou delegar a outro objeto.
Os exemplos mais comuns são proxies remotos, inicializadores de objetos pesados e proxies de acesso.
Proxy Remoto - o assunto está no servidor remoto, em JVM diferente ou mesmo em um sistema não Java. O proxy converte chamadas de método para chamadas RMI / REST / SOAP ou o que for necessário, protegendo o cliente da exposição à tecnologia subjacente.
Lazy Load Proxy - inicialize totalmente o objeto apenas no primeiro uso ou no primeiro uso intensivo.
Proxy de acesso - controle o acesso ao assunto.
Fachada
Fachada está intimamente associada ao Princípio do Menos Conhecimento do Projeto (Lei de Demeter). Fachada é muito semelhante ao adaptador. Ambos envolvem, ambos mapeiam um objeto para outro, mas diferem na intenção. Fachada nivela a estrutura complexa de um assunto, gráfico de objetos complexos, simplificando o acesso a uma estrutura complexa.
Fachada envolve uma estrutura complexa, fornecendo uma interface plana para ela. Isso evita que o objeto cliente seja exposto a relações internas na estrutura do sujeito, promovendo assim um acoplamento flexível.
Ponte
Variante mais complexa do padrão do adaptador, onde não apenas a implementação varia, mas também a abstração. Acrescenta mais um indireto à delegação. A delegação extra é a ponte. Ele desacopla o adaptador até da interface de adaptação. Aumenta a complexidade mais do que qualquer outro padrão de empacotamento, portanto, aplique com cuidado.
Diferenças nos construtores
Diferenças de padrão também são óbvias quando se olha para seus construtores.
O proxy não está quebrando um objeto existente. Não há assunto no construtor.
O Decorator e o Adapter envolvem o objeto já existente, e isso geralmente é
fornecido no construtor.
O construtor Facade pega o elemento raiz de um gráfico de objeto inteiro, caso contrário, parece o mesmo que o Adapter.
Exemplo da vida real - Adaptador Marshalling JAXB . O objetivo deste adaptador é mapear uma classe simples e plana para uma estrutura mais complexa requerida externamente e evitar a classe de assunto "poluente" com anotações excessivas.