PADRÕES DE PROJETOS
Published: 2020-12-21 14:31:16

#INTRODUÇÃO

Segundo o [Wikipédia](https://pt.wikipedia.org/wiki/Padr%C3%A3o_de_projeto_de_software), padrões de projeto é uma solução de software para resolver determinado problema. Eles interagem como template para codificação ou manutenção de software. Segundo Christopher Alexander (1977), cada padrão tenta solucionar problemas que ocorre repetidamente ao longo do seu desenvolvimento. 

##COMPORTAMENTAIS
Padrões Comportamentais são padrões que descreve a comunicação entre objetos ou classes
###Strategy
Este padrão está documentado no catálogo GOF(_Gang of Four_), a intenção deste padrão é criar uma estratégia para classes que fazem serviços específicos e delegar o algoritmo para uma instância de _Strategy_. A figura 1 abaixo representa o diagrama de classe deste padrão.


<figure class="image">
  <img src="https://robsoncastilho.files.wordpress.com/2011/04/strategy.gif" alt="figura 01" widht="10">
  <figcaption >Figura 1 - Diagrama de classe Padrão _Strategy_</figcaption>
</figure>

De acordo com a figura 1 o context representa as classes clientes das classes de _Strategy_. As classes concretas de _Strategy_ se responsabilizam por dar vida a família de classes proposta pelo padrão. Contextinterface() representa uma série de métodos de trabalho com instâncias _Strategy_ como:  _getter & setter_.

Este padrão possui três principais participantes:

* Strategy: é uma interface comum para todas as subclasses ou todos os algoritmos suportados;
* Context: usa a interface _strategy_ para chamar as subclasses;
* ConcreteStrategy: é aquele que vai acessar um dos algoritmos das subclasses da _strategy()_

**USO DO PADRÃO STRATEGY**
* Quando a classe esta bastante acoplada devido ao uso de if/else;
* Quando alguma estrutura específica precisa ser encapsulada.

**VANTAGENS**
* Fácil manutenção;
* Facilita a inserção de novos comportamentos;
* suscetível à mudanças.

**DESVANTAGENS**
* Lentidão, pois é o preço que se paga ao fazer as classes se comunicarem com o contexto;
* O contexto pode iniciar e carregar parâmetros que nunca serão utilizados.

###PADRÃO STATE
Assim como os grandes clipes de sucesso que usa de muitos conceitos e simbolismos este padrão também utiliza dessas artimanhas utilizando o conceito que é super tendência na área de matemática aplicada a computação [Máquina de estados finita](https://pt.wikipedia.org/wiki/M%C3%A1quina_de_estados_finita). Utilizamos ele quando queremos justamente que o comportamento de um objeto mude, de acordo com o seu estado atual. "O padrão encapsula os estados em classes separadas e delega as tarefas para o objeto que representa o estado atual, nós sabemos que os comportamentos mudam juntamente com o estado interno." [(DevMedia, 2010)](https://www.devmedia.com.br/design-patterns-state-parte-4/16783)

**VANTAGENS**
* Conseguimos enxergar melhor os benefícios do polimorfismo;
* Facilita a implementação de testes;
* Aumenta a coesão do código.

**DESVANTAGENS**
* Aumenta bastante o número de classes e códigos que são gerados conforme a complexidade dos estados da aplicação;

**USO DO PADRÃO STATE**
Este padrão é indicado quando se quer modelar domínios que possuem estados diferentes onde o comportamento pode mudar de acordo com cada estado, construindo basicamente uma máquina de estados, mas mantendo uma organização e separação de responsabilidades em classes concretas para cada estado.

###PADRÃO OBSERVER
O próprio nome do padrão já é bem intuitivo para se descobrir o que ele se propõe a fazer, no caso ele vai observar estados para poder notificar a outros objetos quando ocorrer uma mudança.

```java
import java.util.Observable;

public class RevistaInformatica extends Observable {

	private int edicao;

	public void setNovaEdicao(int novaEdicao) {
		this.edicao = novaEdicao;

		setChanged();
		notifyObservers();
	}

	public int getEdicao() {
		return this.edicao;
	}

}
```
O código acima demonstra o uso do padrão observer que utiliza a API do java. Devido a problemas de reutilização que ocorre com uso dessa api vários desenvolvedores preferem construir o Observable.

* [API Observer.](http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Observer.html)
* [API Observable.](Disponível em http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Observable.html)

```java
import java.util.Observer;

class Assinante1 implements Observer {

	Observable revistaInformatica;

	int edicaoNovaRevista;

	public Assinante1(Observable revistaInformatica) {
		this.revistaInformatica = revistaInformatica;
		revistaInformatica.addObserver(this);
	}

	@Override
	public void update(Observable revistaInfSubject, Object arg1) {
		if (revistaInfSubject instanceof RevistaInformatica) {
			RevistaInformatica revistaInformatica = (RevistaInformatica) revistaInfSubject;
			edicaoNovaRevista = revistaInformatica.getEdicao();
			System.out.println("Atenção, já chegou a mais uma edição da Revista Informatica. " +
					"Esta é a sua edição número: " + edicaoNovaRevista);
		}
	}
}
```
Assinante1 é um assinante que se registra na RevistaInformatica para receber notificações sempre que uma nova edição for publicada. 
```java
public static void main(String[] args) {
		//poderia receber a nova edicao atraves de um recurso externo
		int novaEdicao = 3;
		RevistaInformatica revistaInformatica = new RevistaInformatica();
		Assinante1 assinante1 = new Assinante1(revistaInformatica);

		revistaInformatica.setNovaEdicao(novaEdicao);
	}
```
**VANTAGENS**
* Baixo acoplamento entre objetos;
* Adicionar novos objetos sem haver tanta modificação;

**DESVANTAGENS**
* De certa forma pode impactar na performance do sistema;
* Pode haver muitas notificações e sobrecarregar o sistema;

###PADRÃO CHAIN OF RESPONSIBILITY
O padrão chain of responsibility, é um padrão de projeto comportamental que permite você passe pedidos por uma função (handler) com uma finalidade específica para tratar de algum problema. Pode ser um clique de um botão, a alteração de propriedades do objeto, entre outros. Ao receber um pedido, cada handler decide se processa o pedido ou o passa adiante para o próximo handler na corrente.
A figura 2 mostra o diagrama de classe deste padrão.
<figure class="image">
  <img src="https://codechain.files.wordpress.com/2014/07/chainclass.gif" alt="figura 02" widht="10">
  <figcaption >Figura 2 - Diagrama de classe Padrão _chain of responsibility_</figcaption>
</figure>

**FUNCIONAMENTO DO PADRÃO**
como mostra a figura acima existem três participantes neste modelo:
* Handle - define uma interface para tratar as solicitações;
* ConcreteHandler1 e ConcreteHandler2: trata de solicitações pelas quais é responsável;
* Cliente - inicia a solicitação para qualquer objeto ConcreteHandler da cadeia.

No exemplo abaixo onde um usuário qualquer pode efetuar pagamentos e decidir em qual banco quer pagar, é possivel notar que o uso do padrão acabou com a estrutura de decisão if/else.

```java
//para  o usuario ter a opção de vários bancos
public enum IDBancos{
     banco1,banco2,banco3
}
```
a seguinte classe irá implementar a cadeia de filtros
```java
public abstract class BancoFil {
    //atributos da classe
    protected BancoFil next;
    protected IDBancos identificadorDoBanco;
    //construtor
    public BancoFil(IDBancos id) {
        next = null;
        identificadorDoBanco = id;
    }
    //referência para o próximo objeto da corrente
    public void setNext(BancoFil forma) {
        if (next == null) {
            next = forma;
        } else {
            next.setNext(forma);
        }
    }
}
```
Agora devemos criar o método para escolher o pagamento:
```java
public void efetuarPagamento(IDBancos id) throws Exception {
    if (podeEfetuarPagamento(id)) {
        efetuaPagamento();
    } else {
        if (next == null) {
            throw new Exception("banco não cadastrado");
        }
        next.efetuarPagamento(id);
    }
}
 
private boolean podeEfetuarPagamento(IDBancos id) {
    if (identificadorDoBanco == id) {
        return true;
    }
    return false;
}
 
protected abstract void efetuaPagamento();
```
vamos implementar um banco concreto:
```java
public class Banco1 extends BancoChain {
 
    public Banco1() {
        super(IDBancos.banco1);
    }
 
    @Override
    protected void efetuaPagamento() {
        System.out.println("Pagamento efetuado no banco 1");
    }
}
```
O cliente deste código seria a classe principal:
```java
public static void main(String[] args) {
    BancoChain bancos = new Banco1();
    bancos.setNext(new Banco2());
    bancos.setNext(new Banco3());
     
    try {
        bancos.efetuarPagamento(IDBancos.banco1);
       
    } catch (Exception e) {
        e.printStackTrace();
    }
}

```
**VANTAGENS**
* Evita acoplamento dos transmissores de requisição com os receptores;
* Permite que um conjunto de classes atue como uma classe;
* Facilidade na distribuição de responsabilidade entre os objetos.

**DESVANTAGENS**
* Não existe garantia de que recepção da solicitação

###PADRÃO COMMAND
Este padrão trata de criar uma estrutura para execução de comandos. A estrutura que compõe este padrão é a especificação do que é um comando, o comando propriamente dito e o executor de comandos. Seguindo essa estrutura as solicitação para fazer algo em um objeto específico são encapsuladas.

especificação de um comando Trata-se apenas de um modelo de estrutura que todo comando deve seguir, sem nenhuma implementação real. como pode-se notar no código abaixo o comando é apenas a criação de uma classe abstrata.

```java
public interface Comando {
	
	void executar();

}
```
feito isso o comando precisa ser implementado em uma classe concreta. Este por sua vez vai decidir qual comando ele deve invocar.
```java
public class LigarTV implements Comando { 

	private TV tv;
	private String canal;
	
	public LigarTV(TV tv, String canal) {
		this.tv = tv;
		this.canal = canal;
	}
	
	public void executar() {
		this.tv.ligarTV(this.canal);
	}

}
```
Seguindo o exemplo do material de estudos da disciplina sobre o padrão command, o exemplo trata de uma aplicação de uma casa inteligente, onde ela faz coisas super tecnológicas como por exemplo ligar as luzes quando fica escuro, adaptar o clima, entre outros. Dessa forma o sistema precisa se comunicar com vários tipos de interface. Sendo assim, nosso Invocador só precisa se relacionar com esse objeto que representa uma requisição. 

no exemplo abaixo é tratado como se dá a estrutura da especificação do comando: 
```java
public class Invocador {
	
	private List<Comando> comandos = new LinkedList<Comando>();
	
	public void addComando(Comando comando) {
		this.comandos.add(comando);
	}
	
	public void remComando(Comando comando) {
		this.comandos.remove(comando);
	}
	
	public void ligar() {
		for (Comando comando : ligar) {
			comando.executar();
		}
	}
	// ...
}
```
Temos a especificação e as implementações dos comandos! Agora só falta a implementação do executor.

Esta implementação também é bastante simples, basta criarmos uma classe para representar o executor que possua um método Executar. Este método deve receber uma lista de comandos e executá-los um por um.

```java
public class LigarArCondicionado implements Comando {

    private int temperatura;
    private CondicionadorDeAr condicionador;

    public LigarArCondicionado(CondicionadorDeAr condicionador, int temperatura) {
        this.condicionador = condicionador;
        this.temperatura = temperatura;
    }

    public void executar() {
        condicionador.ligar(this.temperatura);
    }
}
```
Agora a implementação já pode ser usada na função main().
###TEMPLATE METHOD
Este padrão de projeto define o esqueleto de um algoritmo na superclasse, mas deixa as subclasses sobrescrever em etapas específicas do algoritmo sem modificar sua estrutura.

**Quando usar o padrão Template Method?**
* Para implementar partes invariantes de um algoritmo uma única vez e deixar subclasses implementarem o comportamento variável;
* Quando comportamento comum entre subclasses deveria ser fatorado e localizado numa classe comum para evitar duplicação;
* Para controlar extensões de subclasses.

**Exemplo de Implementação**

temos a classe principal “Treinos” que tem o método “treinoDiario()” com a finalidade ser um algoritmo a ser seguido por todas as outras classes que estendem essa classe. Este método não pode ser alterado, todos os treinos devem seguir estas etapas. Porém, as classes “TreinoNoMeioDaTemporada” e “TreinoNoInicioDaTemporada” implementam os métodos abstratos “preparoFisico()” e “jogotreino()”. Ambos estes métodos podem ser modificados dependendo se o treino está sendo feito no início de uma temporada ou no meio dela. Assim, cada método é implementado por sua classe específica, mas sempre seguindo o algoritmo. O método “treinoTatico()” é definido pelo algoritmo e pela classe base, este método é concreto e final, portanto não pode ser alterado e é seguido por todos os treinamentos. Nada impede também de termos métodos concretos que podem ser sobrescritos nas subclasses ou que simplesmente podem ser usados da sua classe base.

```java
public abstract class Treinos {

	final void treinoDiario() {
		preparoFisico();
		jogoTreino();
		treinoTatico();
	}

	abstract void preparoFisico();
	abstract void jogoTreino();

	final void treinoTatico() {
		System.out.println("Treino Tatico");
	}

}

class TreinoNoMeioDaTemporada extends Treinos {

	void preparoFisico() {
		System.out.println("Preparo Fisico Intenso.");
	}

	void jogoTreino() {
		System.out.println("Jogo Treino com Equipe Reserva.");
	}
}

class TreinoNoInicioDaTemporada extends Treinos {

	void preparoFisico() {
		System.out.println("Preparo Fisico Leve.");
	}

	void jogoTreino() {
		System.out.println("Jogo Treino com Equipe Junior.");
	}

}
```
exemplo retirado do [DevMedia](https://www.devmedia.com.br/padrao-de-projeto-template-method-em-java/26656).

O padrão do Template Method sugere que você quebre um algoritmo em uma série de etapas, transforme essas etapas em métodos, e coloque uma série de chamadas para esses métodos dentro de um único método padrão.

###PADRÃO NULL OBJECT
Este padrão faz com que o objeto criado para simular outro objeto com os mesmos contratos, mas sem funcionalidade alguma. Sem estado e sem comportamento real. Os dois tipos são compatíveis entre si já que atendem o mesmo contrato, implementam as mesmas interfaces e possivelmente estendem o mesmo tipo.

É uma forma de evitar o uso do estado nulo de objetos que a maioria das linguagens usam. Quando realmente existe uma necessidade semântica, uma situação que um objeto de um tipo seja nulo, você usa este objeto que atende os mesmos contratos mas não faz nada.

Esta forma tende ser "mais orientada a objeto" por fornecer uma melhor abstração para uma situação de valor desconhecido, evita efeitos colaterais e facilita a codificação que não precisa tratar casos específicos como exceção à regra.
A figura 3 demonstra diagrama de classes do padrão:
<figure class="image">
  <img src="https://lh3.googleusercontent.com/proxy/QucMwoeukLFkW2-PsGZacTCoH9wGg8sG2oQccWt6KjQd8XJLI_z4Keimx8xORGVTTw1wsw4yeLUdycSrK0F-ZarJTtA" alt="figura 01" widht="10">
  <figcaption >Figura 3 - Diagrama de classe Padrão _NULL OBJECT_</figcaption>
</figure>

###PADRÕES CRIACIONAIS
 são técnicas que ajudam controlar como as instâncias de classes são criadas. Todo projeto de software orientado a objetos precisa criar instâncias de suas classes. A seguir serão abordados quatro dos cinco padrões GoF Criacionais.

###PADRÃO SINGLETON
Este padrão Garante que para uma classe específica só possa existir uma única instância, a qual é acessível de forma global e
uniforme.

As responsabilidade de uma classe Singleton são:

* armazenar a única instância existente;
* garante que apenas uma instância será criada;
* provê acesso a tal instância.

Exemplos de uso:

Um único sistema de arquivos, gerenciador de janelas, tabela de
salários (ajuste), leitor de teclado, etc.

Desta forma a implementação deste padrão deve seguir alguns aspectos como:
* Tornar os construtores privados para que ele não posssam ser
chamados externamente;
* Declarar um atributo privado estático;
* E escrever um método publico por exemplo: getInstance() para acessar a instância única.

o exemplo a seguir demonstra o uso do padrão Singleton usado para gerar um código que gere números aleatórios


```java
public final class RandomGenerator {
private static RandomGenerator instance = null;
private RandomGenerator() {}
public double nextNumber() {
return Math.random();
}
public static RandomGenerator getInstance() {
if (instance==null) {
instance = new RandomGenerator();
}
return instance;
}
}

```
Dessa forma, toda vez que uma classe precisar da instância de RandomGenerator, terá que invocar o método getInstance(), que retorna a mesma instância sempre.

```java
public class TesteRandomGenerator {
public static void main(String[] args) {
RandomGenerator gerador;
gerador = RandomGenerator.getInstance();
System.out.println("Numero gerado: " + gerador.nextNumber());
}
}
```
###PADRÃO PROTORYPE
Este padrão permite a criação de novos objetos a partir de um modelo original, ou como o próprio nome indica, um protótipo, que é clonado.

**Exemplo de uso**

O padrão Prototype é aplicado quando existe a necessidade de clonar, literalmente, um objeto. Ou seja, quando a aplicação precisa criar cópias exatas de algum objeto em tempo de execução este padrão é altamente recomendado. O padrão Prototype pode ser útil em sistemas com as seguintes características:

* Sistemas que utilizam classes definidas em runtime;
* Sistemas que utilizam o padrão Abstract Factory, para criação de objetos.
* Sistemas que possuem componentes cujo estado inicial possui poucas variações.

**VANTAGENS**

Uma das principais vantagens da sua utilização é quando a inicialização de um objeto pode se tornar demorada, e você quer fazer algumas pequenas modificações ao inicializar. Nesse contexto, o Prototype pode então evitar a criação “do zero” de novos objetos.

Para compreendermos o padrão declaramos um interface comum para todos os objetos que suportam clonagem. Essa interface permite que você clone qualquer objeto sem acoplar seu código à classe daquele objeto.
```java
public class Caneta {

	private String cor;
	
	public Caneta() {
		
	}
	
	private Caneta(Caneta objetoOrigem) {
		this.cor = objetoOrigem.getCor();
	}

	// Gets e sets

	@Override
	public Caneta clonar() {
		return new Caneta(this);
	}

}
```
Este foi o padrão Prototype. Ele é bem útil em sistemas que precisamos clonar livremente os objetos e que suas definições sejam feitas em tempo de execução.

###PADRÃO BUILDER
O Padrão Builder apoia a separação da construção de um objeto complexo da sua representação podendo construir objetos complexos passo a passo. de forma que o mesmo processo de construção possa criar diferentes representações, baseado em regras e parâmetros que sejam informados ao objeto responsável pela construção.

diagrama UML representando este padrão e seus elementos, conforme descrito no livro do GoF. A figura 4 mostra o diagrama uml do padrão:
<figure class="image">
  <img src="https://miro.medium.com/max/2800/0*wlG6zRO9s94Ujf0f.png" alt="figura 01" widht="10">
  <figcaption >Figura 4 - Diagrama de classe Padrão _PADRÃO BUILDER_</figcaption>
</figure>
* Director: Constrói um objeto utilizando a interface do builder;
* Builder: Especifica uma interface para um construtor de partes do objeto-produto;
* ConcreteBuilder: Define uma implementação da interface builder;
* Product: O objeto complexo construído.

Exemplo de Uso:

O padrão Builder é usado para encapsular objetos. Ou seja, quando o processo de construção de um objeto é considerado complexo e também é usado quando se trata da construção de representações múltiplas de uma mesma classe.

Implementações

O código demonstra a implementação do padrão para o exemplo da criação de objetos através de builders específicos:

```C
using System;
using System.Collections.Generic;
 
namespace DoFactory.GangOfFour.Builder.Structural
{
  public class MainApp
  {
    public static void Main()
    {
      Director director = new Director();
 
      Builder b1 = new ConcreteBuilder1();
      Builder b2 = new ConcreteBuilder2();
 
      director.Construct(b1);
      Product p1 = b1.GetResult();
      p1.Show();
 
      director.Construct(b2);
      Product p2 = b2.GetResult();
      p2.Show();
 
      Console.ReadKey();
    }
  }
 
  class Director
  {
    public void Construct(Builder builder)
    {
      builder.BuildPartA();
      builder.BuildPartB();
    }
  }
 
  abstract class Builder
  {
    public abstract void BuildPartA();
    public abstract void BuildPartB();
    public abstract Product GetResult();
  }
 
  class ConcreteBuilder1 : Builder
  {
    private Product _product = new Product();
 
    public override void BuildPartA()
    {
      _product.Add("PartA");
    }
 
    public override void BuildPartB()
    {
      _product.Add("PartB");
    }
 
    public override Product GetResult()
    {
      return _product;
    }
  }
 
  class ConcreteBuilder2 : Builder
  {
    private Product _product = new Product();
 
    public override void BuildPartA()
    {
      _product.Add("PartX");
    }
 
    public override void BuildPartB()
    {
      _product.Add("PartY");
    }
 
    public override Product GetResult()
    {
      return _product;
    }
  }
 
  class Product
  {
    private List<string> _parts = new List<string>();
 
    public void Add(string part)
    {
      _parts.Add(part);
    }
 
    public void Show()
    {
      Console.WriteLine("\nProduct Parts -------");
      foreach (string part in _parts)
        Console.WriteLine(part);
    }
  }
}
```

####Padrões Factory e Method

De forma geral todos os padrões [Factory](https://www.devmedia.com.br/padrao-de-projeto-factory-method-em-java/26348) (Factory Method, Abstract Factory) encapsulam a criação de objetos. O padrão Factory Method por sua vez encapsula a criação de objetos, no entanto, a diferença é que neste padrão encapsula-se a criação de objetos deixando as subclasses decidirem quais objetos criar.

Diferenças:

* Em vez do cliente (que quer criar objetos sem saber as classes exatas) chamar um método de criação (Factory Method), ele de alguma forma possui um objeto (uma Abstract Factory) e usa este objeto para chamar os métodos de criação;

* Onde Factory Method quer que você seja diferente (via herança) para criar objetos diferentes, o Abstract Factory quer que você tenha algo diferente;

* Se ele possuir uma referência a uma Abstract Factory diferente, toda a criação será diferente

* O fato de todos os métodos de criação estarem na mesma subclasse de uma Abstract Factory permite satisfazer a restrição de criar apenas objetos relacionados ou dependentes
Abstract Method

O Factory Method é um padrão criacional de projeto que fornece uma interface para criar objetos em uma superclasse, mas permite que as subclasses alterem o tipo de objetos que serão criados.
Abstract Factory

Prover uma interface para criar uma família de objetos
relacionados ou dependentes sem especificar suas
classes concretas. Este padrão define uma interface para criar todos os produtos distintos, mas deixa a criação real do produto para classes de fábrica concretas.

Quando usar o padrão Abstract Factory?
* Quando um sistema deve ser independente de como seus produtos são criados;
* Quando um sistema deve ser configurado com uma entre várias famílias de produtos;
* Quando você quer fornecer uma biblioteca de classes e quer revelar sua interface e não sua implementação.

para exemplificar como esse metodo funciona você vai prescisar de uma classe abstrata
```java
public abstract class NomeDaClasse {
    //assinatura dos metodos abstratos
}
```
depois voce vai precisar de uma classe concreta que implemente a classe abstrata

````java
public class ClasseConcreta extends ClasseAbstrata {
    //implementação dos metodos abstratos da classe herdada
}
```
##ESTRUTURAIS
Os padrões estruturais explicam como montar objetos e classes em estruturas maiores, mas ainda mantendo essas estruturas flexíveis e eficientes.

###PADRÃO ADAPTER
A utilização de frameworks e biblioteca de terceiros é muito comum durante o desenvolvimento de qualquer software, devido a comodidade e facilidade de utilização.

A proposta desse padrão é quando há a necessidade de trabalhar com classes distintas respondendo a uma interface comum no código.

FUNCIONAMENTO

O padrão [Adapter](https://www.devmedia.com.br/padrao-de-projeto-adapter-em-java/26467) é muito utilizado quando precisamos usar novas bibliotecas de classes, adquirida de outras bibliotecas. Porém, essas bibliotecas de classe do novo fornecedor são diferentes das bibliotecas de classes do fornecedor antigo. Como não temos o código do novo fornecedor e também não podemos alterá-la, o que pode ser feito é criar uma classe que faça essa adaptações.

O Adaptador permite que classes com interfaces incompatíveis trabalhem juntas.

EXEMPLO:
Logo abaixo segue um exemplo de implementação deste padrão. Usando a problemática das novas tomadas de 2 e 3 pinos, onde uma nova interface é criada para poder funcionar em todos os tipos de tomadas.

```java
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");
	}
}
```
 Agora criamos um Adapter para que possamos acessá-la. Herdando da classe que você possui.

```java
public class AdapterTomada extends TomadaDeDoisPinos {
	private TomadaDeTresPinos tomadaDeTresPinos;

	public AdapterTomada(TomadaDeTresPinos tomadaDeTresPinos) {
		this.tomadaDeTresPinos = tomadaDeTresPinos;
	}

	public void ligarNaTomadaDeDoisPinos() {
		tomadaDeTresPinos.ligarNaTomadaDeTresPinos();
	}
}
```

Vantagens de Usar o Padrão Adapter

vinculação do cliente a uma interface e não a uma implementação e flexibilidade com o uso de diversos adaptadores.

###Padrão Facade
De forma mais simples podemos dizer que o padrão [Facade](https://www.devmedia.com.br/padrao-de-projeto-facade-em-java/26476) tem como objetivo esconder a complexidade de um sistema expondo apenas as interfaces que o cliente precisa enxergar. Com isso o sistema fica mais simples e fornece uma coleção de métodos mais fáceis de entender.

A definição oficial do padrão Facade é:

“O Padrão Facade fornece uma interface unificada para um conjunto de interfaces em um subsistema. O Facade define uma interface de nível mais alto que facilita a utilização do subsistema”.

Objetivos:
* Abstrair/simplificar a complexidade de um sub-sistema;
* Desacoplar o sistema, favorecendo a separação de responsabilidades;
* Reduzir a dependência;

DIAGRAMA DA UML DO PADRÃO FACADE

<figure class="image">
  <img src="https://www.ateomomento.com.br/wp-content/uploads/2015/11/facade-design-pattern.png" alt="figura 01" widht="10">
  <figcaption >Figura 5 - Diagrama de classe Padrão _FACADE_</figcaption>
</figure>

Como podemos observar no diagrama acima as classes Client1 e Client2 somente acessam as classes Class1, Class2 e Class3 através da classe Façade. Isso serve para isolar o conjunto de classes

O [exemplo](https://www.devmedia.com.br/padrao-de-projeto-facade-em-java/26476) abaixo de codigo em java representa os metodos que precisam ser executados para ligar o computador.
```java
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);
	}
}
```
Neste exemplo o facade é utilizado para encapsular a complexidade  de classes e métodos envolvidos quando precisamos inicializar o computador. 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.

###Padrão Decorator

Anexa responsabilidades adicionais a um objeto dinamicamente. Provê uma alternativa flexível para extensão de funcionalidade, sem ter que usar Herança [(DevMedia)](https://docs.oracle.com/javase/8/docs/api/java/io/package-frame.html).

Funcionamento

A descrição original do Padrão Decorator é: "O Padrão Decorator anexa responsabilidades adicionais a um objeto dinamicamente. Os decoradores fornecem uma alternativa flexível de subclasse para estender a funcionalidade".

Elementos do padrão Decorator

* Definição abstrata de um componente de software;
* Implementação concreta deste componente;
* Definição abstrata de um decorator para este componente;
* Uma ou mais implementações concretas do decorator do componente;

O Java também utiliza bastante o padrão de projeto Decorator. A API [java.io](https://docs.oracle.com/javase/8/docs/api/java/io/package-frame.html) é amplamente baseada nesse padrão de projeto.

Implementação do Padrão Decorator

````java
abstract class Pessoa {

	public abstract void VirarZumbi();

}

class PessoaSimples extends Pessoa {

	public void VirarZumbi() {
		System.out.println(“virou zumbi”);
	}
}

abstract class PessoaDecorator extends Pessoa {

	protected Pessoa pessoaZumbi;

	public PessoaDecorator(Janela pessoaZumbi) {
		this.pessoaZumbi = pessoaZumbi;
	}

}
```
Nesse exemplo criou-se uma pessoa simples onde queremos adicionar caracteristicas de pessoa que vira um zumbi ou estão alucinadas. Assim, criou-se também a classe PessoaDecorator que será estendida pelos nossos decoradores que irão inserir propriedades na nossa Pessoa.
````java
class DecoradorAtaques extends PessoaDecorator {

	public DecoradorAtaques(Pessoa pessoaZumbi) {
		super(pessoaZumbi);
	}

	public void VirarZumbi() {
		ZumbiAtaque();
		pessoaZumbi.VirarZumbi();
	}

	private void ZumbiAtaque() {
		System.out.println(“a pessoa zumbi ataca”);
	}

}
```
O decorador que anexa ataque ao nosso componente principal (pessoaSimples). Portanto, anexamos responsabilidades ao nosso componente base. Se quiséssemos criar caracteristicas como pele apodrecida e com roupas esfarrapadas, com um cheiro forte e horrível, faríamos outros decoradores para anexar mais responsabilidades.

CONCLUSÃO:

O padrão Decorator usa a herança apenas para ter uma correspondência de tipo e não para obter o comportamento.

##PADRÃO PROXY

O padrão Proxy proporciona um espaço reservado para outro objeto controlar o acesso a ele. A classe proxy teoricamente pode se conectar a qualquer objeto.

O exemplo abaixo demostra o uso do padrão em um código responsável por mostra imagens.
```java
import java.util.*;

interface Imagem {
    public void mostrarImagem();
}

// no Sistema A
class ImagemReal implements Imagem {
private String nomeDoArquivo;
    public ImagemReal(String nomeDoArquivo) {
    this.nomeDoArquivo = nomeDoArquivo;
    carregarImagemDoDisco();
}

private void carregarImagemDoDisco() {
    System.out.println("Carregando " + nomeDoArquivo);
}

public void mostrarImagem() {
        System.out.println("Mostrando " + nomeDoArquivo);
    }
}

// no Sistema B
class ImagemProxy implements Imagem {
    private String nomeDoArquivo;
    private Imagem imagem;

public ImagemProxy(String nomeDoArquivo) {
    this.nomeDoArquivo = nomeDoArquivo;
}
public void mostrarImagem() {
    if(imagem == null)
      imagem = new ImagemReal(nomeDoArquivo);
    imagem.mostrarImagem();
}
}

class ExemploProxy {
    public static void main(String[] args) {
        Imagem imagem1 = new ImagemProxy("ResOi_10MB_Foto1");
        Imagem imagem2 = new ImagemProxy("ResOi_10MB_Foto2");

        imagem1.mostrarImagem(); // é necessário o carregamento
        imagem1.mostrarImagem(); // não é necessário o carregamento
        imagem2.mostrarImagem(); // é necessário o carregamento
        imagem2.mostrarImagem(); // não é necessário o carregamento
        imagem2.mostrarImagem(); // não é necessário o carregamento
        imagem1.mostrarImagem(); // não é necessário o carregamento
    }
}
```
o propósito de se criar um Proxy Objeto é criar um representante de outro Objeto.

##PADRÃO BRIDGE
Este padrão é utilizado quando queremos separar a abstração da implementação figura 04.
<figure class="image">
  <img src="https://miro.medium.com/max/1330/0*MJzJYVp58O4gQ2zO.png" alt="figura 02" widht="10">
  <figcaption >Figura 4 - Diagrama de classe Padrão _BRIDGE_</figcaption>
</figure>

* Abstraction: é uma classe abstrata, que define as abstrações das regas de negocio;
* RedefinedAbstraction: Essa classe herda da classe abstrata Abstraction, estendendo a interface definida por ela;
* Bridge: Interface que liga a classe de abstração com a de implementação, deixando a classe de implementação independente da classe de abstração.
* ImplementationA e ImplementationB: Classes que implementam a interface Bridge. Responsáveis por prover os detalhes de implementação para a abstração associada a ligação.

 O padrão Bridge é bastante utilizado em estrutura como pontes para conexões a bancos de dados JDBC, implementações de renderização gráfica em diferentes plataformas, e uma das mais famosas, a implementação de listas no Java.

###PADRÃO COMPOSITE

Este padrão aplica polimorfismo para chamar métodos de um objeto na árvore sem se preocupar se ele é uma folha ou um composto.
A intenção do padrão Composite é compor objetos em estruturas de árvore para representar hierarquia partes-todo.

**USO DO PADRÃO**

Quando precisamos de  uma hierarquia de objetos que representem uma mesma super-classe. Através do padrão Composite, todos terão uma forma comum de serem reconhecidos e trabalhados, através de uma super-classe.

Abaixo temos a UML do pattern, descrita no livro do GoF. 

<figure class="image">
  <img src="https://upload.wikimedia.org/wikipedia/commons/3/3d/CompositeBasic.gif" alt="figura 01" widht="10">
  <figcaption >Figura 6 - Diagrama de classe Padrão _Composite_</figcaption>
</figure>
* Component: declara a interface para objetos nessa composição;
*  Leaf: representa o objeto folha na composição;
* Composite: define o comportamento para componentes que possuam componentes-filho;
* Client: lida com objetos da composição através da interface do Componente.
**REFERÊNCIAS**:

HEYWORTH, James, Introduction to Design Patterns in Delphi. Acesso em: 20 nov. 2020.

GAMMA, Erich, HELM, Richard; JOHNSON, Ralph, VLISSIDES, John.“Padrões de Projeto: soluções reutilizáveis de software orientado a objetos”. 1. ed. Porto Alegre: Bookman, 2000.

Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra. Head First Design Patterns. O'Reilly Media, 2004.

DevMedia. Disponível em: <https://www.devmedia.com.br/entendendo-os-conceitos-dos-padroes-de-projetos-em-java/29083>. Acesso em: 10 nov. 2020.