2.1 Adaptador
Adapter (Adaptador) é um padrão de projeto estrutural projetado para organizar o uso das funções de um objeto que não está disponível para modificação por meio de uma interface especialmente criada.
A definição oficial é um pouco complicada, mas se você descrevê-la com suas próprias palavras, um adaptador é um padrão de design que permite que objetos com interfaces incompatíveis trabalhem juntos .

Usado para organizar o uso das funções de um objeto que não está disponível para modificação por meio de uma interface especialmente criada. Uma classe adicional é criada com a interface necessária e essa classe, por sua vez, chama os métodos do objeto desejado (que não possui a interface necessária).
Importante! Se no código você encontrar o sufixo Adapter para uma classe, terá todo o direito de considerar que essa classe atua como um adaptador e está associada a um grupo de classes que funcionam de acordo com o esquema descrito acima.
É usado nos casos em que o sistema suporta os dados e comportamentos necessários, mas possui uma interface inadequada. O uso mais comum do padrão Adapter é quando você deseja criar uma classe herdada de uma classe abstrata nova ou existente.
Forças:
- A transição para o uso de outras classes externas não requer reformulação do sistema em si, basta implementar mais uma classe Adapter.
- Independência da implementação de classes externas (classes de bibliotecas cujo código não podemos alterar). Seu programa se torna independente da interface de classes externas.
2.2 Decoradores
Decorator é um padrão de design estrutural para anexar dinamicamente comportamento adicional a um objeto. O padrão Decorator fornece uma alternativa boa e flexível para a prática de subclasses para estender a funcionalidade.

Usado para conectar dinamicamente obrigações adicionais a um objeto.
Muitos de vocês perguntarão: como você pode adicionar dinamicamente (enquanto o programa está em execução) um novo comportamento a um objeto? Um objeto pode ser montado a partir de peças, ou seja, pequenos objetos. Lembra das cadeias de filtros em servlets? Ou a API Stream quando você escreveu uma consulta usando filter(), map(), list()?
IntStream.of(50, 60, 70, 80, 90).filter(x -> x < 90).map(x -> x + 10).limit(3).forEach(System.out::print);
Pontos fortes do padrão Decorator:
- Não há necessidade de criar subclasses para estender a funcionalidade de um objeto.
- A capacidade de conectar dinamicamente novas funcionalidades em qualquer lugar: antes ou depois da funcionalidade principal do objeto ConcreteComponent.
2.3 Proxies
Proxy é um padrão de projeto estrutural que fornece um objeto que controla o acesso a outro objeto, interceptando e passando por todas as suas chamadas.

O padrão Proxy fornece um objeto substituto no lugar do objeto real. Este objeto controla o acesso ao objeto original. Usado com muita frequência.
Lembra como usamos o framework Mockito e interceptamos uma chamada para um objeto real usando o método Mockito.spy() ou a anotação @Spy? Foi então que foi criado um objeto Proxy especial, por onde passaram todas as chamadas ao objeto original.
E então poderíamos gerenciar essas chamadas adicionando regras ao objeto. Isso mesmo - o objeto original não muda e trabalhar com ele se torna muito mais flexível. É especialmente útil quando não chamamos o objeto proxy de nosso código, mas o passamos em algum lugar. Controlando assim a comunicação de dois objetos independentes de nós.
Tipos de procurações por finalidade:
- Proxy de registro : registra todas as chamadas para o “Assunto” com seus parâmetros.
- Proxy remoto (proxies remotos): permite a comunicação com o “Assunto”, que está em um espaço de endereçamento diferente ou em uma máquina remota. Também pode ser responsável por codificar a solicitação e seus argumentos e enviar a solicitação codificada ao “Assunto” real.
- Proxy virtual (proxies virtuais): garante que o "Assunto" real seja criado somente quando for realmente necessário. Ele também pode armazenar em cache algumas das informações sobre o "Assunto" real para atrasar sua criação.
- Copy-on-write : Fornece uma cópia do "assunto" quando o cliente executa determinadas ações (um caso especial do "proxy virtual").
- Proxies de proteção : podem verificar se o chamador possui as permissões necessárias para fazer a solicitação.
- Caching Proxy : Fornece armazenamento temporário de resultados de cálculo antes de servi-los a vários clientes que podem compartilhar os resultados.
- Screening Proxy: Protege o "Assunto" de clientes perigosos (ou vice-versa).
- Synchronization Proxy : executa o controle de acesso sincronizado ao “Assunto” em um ambiente multi-thread assíncrono.
- Link “inteligente” (proxy de referência inteligente): executa ações adicionais quando um link para o “Assunto” é criado, por exemplo, calcula o número de links ativos para o “Assunto”.
2.4 Ponte
O padrão Bridge é um padrão de design estrutural usado para "separar abstração e implementação para que possam mudar independentemente".
O padrão de ponte usa encapsulamento, agregação e pode usar herança para compartilhar a responsabilidade entre as classes.

Quando a abstração e a implementação são separadas, elas podem mudar independentemente. Em outras palavras, quando implementado por meio do padrão de ponte, a alteração da estrutura da interface não interfere na alteração da estrutura da implementação.
Considere essa abstração como uma figura. Existem muitos tipos de formas, cada uma com suas próprias propriedades e métodos. No entanto, há algo que une todas as figuras. Por exemplo, cada forma deve ser capaz de se desenhar, dimensionar e assim por diante.
Ao mesmo tempo, o desenho de gráficos pode diferir dependendo do tipo de sistema operacional ou biblioteca de gráficos. As formas devem ser capazes de se desenhar em vários ambientes gráficos. Mas é impraticável implementar todos os métodos de desenho em cada forma, ou modificar a forma toda vez que o método de desenho muda.
Nesse caso, o padrão bridge ajuda, permitindo criar novas classes que irão implementar o desenho em diversos ambientes gráficos. Usando essa abordagem, é muito fácil adicionar novas formas e maneiras de desenhá-las.
A conexão representada pela seta nos diagramas pode ter 2 significados: a) “um tipo”, de acordo com o princípio de substituição de Liskov, eb) uma das possíveis implementações da abstração. As linguagens normalmente usam herança para implementar a) e b), o que tende a inchar as hierarquias de classes.
A ponte serve exatamente para resolver esse problema: objetos são criados em pares a partir de um objeto de uma classe de hierarquia A e hierarquia B, herança dentro da hierarquia A tem o significado de “variedade” segundo Liskov, e para o conceito de “implementação de abstração” um link do objeto A para seu objeto emparelhado B é usado.
2.5 Fachada
O padrão Facade é um padrão de projeto estrutural que oculta a complexidade de um sistema, reduzindo todas as chamadas externas possíveis a um único objeto que as delega aos objetos apropriados no sistema.

Como fornecer uma interface unificada com um conjunto de implementações ou interfaces díspares, por exemplo, para um subsistema, se o acoplamento forte a esse subsistema for indesejável ou se a implementação do subsistema puder mudar?
Defina um ponto de interação com o subsistema - um objeto de fachada que fornece uma interface comum com o subsistema e atribua a ele a responsabilidade de interagir com seus componentes. Uma fachada é um objeto externo que fornece um único ponto de entrada para os serviços do subsistema.
A implementação de outros componentes do subsistema é privada e não visível para componentes externos. O objeto Facade fornece uma implementação do padrão GRASP Resistente a mudanças em termos de proteção contra mudanças na implementação do subsistema.
Importante! Este padrão é usado quando queremos esconder completamente algum grupo de objetos e passar toda a comunicação com eles através do nosso objeto. Se você deseja apenas fornecer algum controle sobre o processo de comunicação dos objetos e não necessariamente ocultá-los, é melhor usar o padrão Proxy.
GO TO FULL VERSION