-
Padrão GoF
-
Padrões de Criação
-
Abstract Factory
- Permite a criação de famílias de objetos relacionados ou dependentes por meio de uma única interface e sem que a classe concreta seja especificada.
-
Builder
- Permite a separação da construção de um objeto complexo da sua representação, de forma que o mesmo processo de construção possa criar diferentes representações.
-
Factory Method
- Permite as classes delegar para subclasses decidirem. O factory method permite delegar a instanciação para as subclasses.
-
Prototype
- Permite a criação de objetos a partir de um modelo original, ou protótipo.
-
Singleton
- Garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto.
-
Padrões Estruturais
-
Definição
- Padrões estruturais "se preocupam com a forma como classes e objetos são compostos para formar estruturas maiores". Segundo eles, "os padrões estruturais de classes utilizam a herança para compor interfaces ou implementações". Os padrões estruturais de objetos, por sua vez, "descrevem maneiras de compor objetos para obter novas funcionalidades".
- Os padrões estruturais tratam problemas referentes à estrutura de classes e objetos. Ou melhor, de como vencer as limitações da estrutura da programação orientada a objetos para tornar as aplicações mais flexíveis.
- Você usará o padrão Adapter quando quiser usar uma classe existente, mas sua interface não corresponder àquela que você necessita.
-
Adapter
- Permite que classes com interfaces incompatíveis possam interagir.
-
Exemplo:
- Vamos imaginar o seguinte cenário. Você tem uma aplicação que conversa com dois bancos de dados. Um deles é relacional, baseado em tabelas e registros. O outro é orientado a documentos, trabalha com o conceito de chave-valor. Existem duas classes prontas para persistir dados nesses dois bancos, respectivamente RecordManager e DocumentManager.
- O problema é que os métodos de persistência são diferentes. A classe RecordManager tem um método save() que recebe um objeto da classe Record. A classe DocumentManager, por sua vez, tem um método chamado persist() que recebe uma variável HashMap<String,String>. E na aplicação, os objetos que contêm os dados para serem persistidos são da classe AbstractEntity.
- Se pudéssemos fazer uma analogia com o mundo físico, poderíamos dizer que você tem que ligar dois aparelhos em um quadro de tomadas. Esse quadro recebe tomadas de dois pinos chatos. Só que seus dois aparelhos tem plugues completamente diferentes. Um tem dois pinos cilíndricos e o outro, pra piorar, tem três pinos chatos, só que em disposição diferente do que a tomada espera.
-
Bridge
- Utilizado quando é desejável que uma interface (abstração) possa variar independentemente das suas implementações.
-
Composite
- Constituído pela composição de objetos similares a ele;
Utilizado para representar listas recorrentes - ou recursivas - de elementos;
Permite que os elementos contidos em um objeto composto sejam tratados como se fossem um único objeto.
-
Decorator
- Permite adicionar um comportamento a um objeto já existente em tempo de execução, ou seja, agrega dinamicamente responsabilidades adicionais a um objeto.
- O padrão Decorator deve ser utilizado quando você precisa acrescentar e/ou remover responsabilidades de objetos individuais de forma dinâmica (em tempo de execução). O padrão Decorator também permite que você combine as funcionalidades de várias classes em uma sem estabelecer uma ligação obrigatória, superando as limitações da herança simples do Java. E observe que a arquitetura do Decorator permite que você "herde" somente os comportamentos que interessam. Como a classe "decorada" não sabe o que os "decoradores" fazem além do que foi definido pela interface comum, não há sobrecarga de atributos e métodos.
-
Problema
- Quando queremos que classes diferentes compartilhem características comuns, criamos uma superclasse, que reúna tudo o que for genérico. Isso, porém, tem limitações.
- O estabelecimento de herança é algo estático, que deve estar definido antes da execução do programa. Não é possível definir generalizações em tempo de execução.
- Outra questão é que em Java, especificamente, não há herança múltipla. Isso significa que só é possível herdar características e comportamentos de uma única classe, de forma direta.
- Vamos imaginar a seguinte situação. Nós temos uma classe chamada Carta, que monta uma carta. Uma carta pode ter os seguintes elementos: endereço, data, endereço do destinatário, referências, saudação, o texto, a conclusão, a assinatura e o post-scriptum. Observe o verbo: pode ter, não deve ter.
- Isso significa que uma carta pode ser uma combinação desses elementos, que não estarão, obrigatoriamente, todos juntos. Sendo assim, ter uma classe Carta que crie todos esses elementos implica ter recursos que não serão usados sempre, exceto o elemento texto. Se você quiser montar uma carta que tenha somente saudação e texto, por exemplo, o que fará?
- É claro que você pode ter atributos que omitam a criação dos elementos na montagem da carta, mas isso não removerá o comportamento desnecessário que a classe encapsula. Seria melhor que o comportamento pudesse ser adicionado ao objeto em tempo de execução. Que ao criar o objeto, nós pudéssemos dizer o que ele pode fazer.
- Para resolver isso, podemos usar o padrão Decorator.
-
Facade
- Disponibiliza uma interface simplificada para uma das funcionalidades de uma API.
-
Flyweight
- Apropriado quando vários objetos devem ser manipulados, e esses não suportam dados adicionais.
-
Proxy
- Classe que funciona como uma interface para outra classe.
- Quando você precisar que um objeto tenha um substituto, que trate todas as demandas que não têm relação direta com ele, é sinal de que deve aplicar o padrão Proxy.
- O Proxy também serve para limitar a quantidade de recursos disponíveis em uma API. Às vezes uma API possui uma série de recursos, e uma miríade de modos de fazer alguma coisa. Se os programadores tiverem a liberdade de usar a API diretamente, sem uma padronização, podem criar um sério problema de manutenção, decorrente da complexidade gerada pela falta de legibilidade do código. Quer dizer, ações similares são executadas pela aplicação de modo diferente de acordo com a pessoa que implementou.
- Um modo de forçar a padronização é criar Proxies para as classes da API, limitando as formas possíveis de manipulá-la.
-
Problema
- Em algumas situações, criar um objeto de uma determinada classe é algo caro ao sistema. Se o objeto faz uso intensivo de recursos externos do sistema que afetam o desempenho, como leitura e gravação de disco, ou qualquer comunicação com dispositivos externos, não faz sentido criá-lo nem mantê-lo se ele não será utilizado. E pode ocorrer que a configuração dos atributos do objeto, necessária para a execução dos métodos que se comunicam com os recursos externos, ocorra em momentos diferentes da aplicação, de modo que ele só abrirá conexões com recursos, mas só as utilizará depois de algum tempo.
- Seria ideal que isso ocorresse por demanda. Que nós criássemos o objeto, configurássemos de uma vez tudo o que fosse necessário e executássemos os métodos que precisamos.
- Vamos imaginar, por exemplo, uma classe chamada Pdf, que cria arquivos PDF. Ela permite que nós criemos o documento, montemos as páginas, incluamos o conteúdo nas páginas e montemos o índice. Com tudo isso definido, ela nos permite gravar o documento, ou criá-lo de verdade, em um disco, onde fique persistente.
- O problema é que essa classe já abre um recurso para gravação de arquivo quando é instanciada. E a configuração de todos os seus atributos, para geração do arquivo, pode ser feita em momentos diferentes, fazendo com que um recurso fique aberto por um intervalo de tempo em que não é utilizado.
- Nós poderíamos ter alguma forma de adiar a instanciação do objeto, até que tivéssemos realmente todos os dados necessários para criar o arquivo, configuração e chamada do método gerador em sequência, de uma só vez.
-
Padrões Comportamentais
-
Chain of Responsability
- Representa um encadeamento de objetos receptores para o processamento de uma série de solicitações diferentes. Esses objetos receptores passam a solicitação ao longo da cadeia até que um ou vários objetos a tratem.
-
Command
- Encapsular uma solicitação como um objeto, desta forma permitindo que clientes parametrizem diferentes solicitações, enfileirem ou façam o registro (log) de solicitações e suportem operações que podem ser desfeitas.
-
Interpreter
- Utilizado para representar e resolver problemas recorrentes que possam ser expressos sob a forma de uma linguagem formal simples.
-
Iterator
- Permite a um programador examinar um container.
-
Mediator
- Desacopla e gerencia as colaborações entre um grupo de objetos. Define um objeto que encapsula as interações dentro desse grupo.
-
Memento
- Permite armazenar o estado interno de um objeto em um determinado momento, para que seja possível retorná-lo a este estado, caso necessário.
-
Observer
- Define uma dependência um-para-muitos entre objetos de modo que quando um objeto muda o estado, todos seus dependentes são notificados e atualizados automaticamente. Permite que objetos interessados sejam avisados da mudança de estado ou outros eventos ocorrendo num outro objeto.
-
State
- Usado quando o comportamento de um objeto muda, dependendo do seu estado.
-
Strategy
- Permite definir novas operações sem alterar as classes dos elementos sobre os quais opera. Definir uma família de algoritmos e encapsular cada algoritmo como uma classe, permitindo assim que elas possam ser trocados entre si. Este padrão permite que o algoritmo possa variar independentemente dos clientes que o utilizam.
-
Template Method
- Fornece uma estrutura fixa, de um algoritmo, esta parte fixa deve estar presente na superclasse, sendo obrigatório uma classeAbstrata que possa conter um método concreto.
-
Visitor Pattern
- Permite que se crie uma nova operação sem que se mude a classe dos elementos sobre as quais ela opera.
-
Padrão GRASP
- Controller
- Creator
- Expert
- High Cohesion
- Indirection
- Law of Demeter
- Low Coupling
- Polymorphism
-
Padrão J2EE
-
Camada de Apresentação
- Intercepting Filter
- Front Controller
- Application Controller
- Context Object
- View Helper
- Composite View
- Dispatcher View
- Service To Worker
-
Camada de Negócio
- Application Service
- Business Delegate
- Service Locator
- Session Facade
- Transfer Object
- Business Object
- Value List Handler
- Composite Entity
- Transfer Object Assembler
-
Camada de Integração
- Service Activator
- Domain Store
- Web Service Broker
- Data Access Object