Padrões de Design em Java – Tutorial com Exemplos

Introdução

Padrões de design são muito populares entre os desenvolvedores de software. Um padrão de design é uma solução bem descrita para um problema comum de software.

Alguns dos benefícios de usar padrões de design são:

  1. Os padrões de design já estão definidos e fornecem uma abordagem padrão da indústria para resolver um problema recorrente, então economiza tempo se usarmos sensatamente o padrão de design. Existem muitos padrões de design em Java que podemos usar em nossos projetos baseados em Java.
  2. O uso de padrões de design promove a reutilização que leva a um código mais robusto e altamente mantível. Isso ajuda a reduzir o custo total de propriedade (TCO) do produto de software.
  3. Como os padrões de design já estão definidos, torna nosso código fácil de entender e depurar. Isso leva a um desenvolvimento mais rápido, e novos membros da equipe o entendem facilmente.

Os padrões de design em Java são divididos em três categorias – criacionais, estruturais e comportamentais.

Este artigo serve como um índice para todos os artigos sobre padrões de design em Java.

Padrões de Design Criacionais

Padrões de design criacionais fornecem soluções para instanciar um Object da melhor maneira possível para situações específicas.

1. Padrão Singleton

O padrão singleton restringe a instanciação de uma Class e garante que apenas uma instância da classe exista na Máquina Virtual Java. A implementação do padrão singleton sempre foi um tópico controverso entre os desenvolvedores.

Nota: Saiba mais sobre o Padrão de Design Singleton.

2. Padrão Factory

O padrão de design factory é usado quando temos uma superclasse com várias subclasses e, com base na entrada, precisamos retornar uma das subclasses. Este padrão retira a responsabilidade da instanciação de uma Class do programa cliente para a classe factory. Podemos aplicar um padrão singleton na classe factory ou tornar o método da factory static.

Nota: Saiba mais sobre o Padrão de Design Factory.

3. Padrão de Fábrica Abstrata

O padrão de fábrica abstrata é semelhante ao padrão de fábrica e é uma fábrica de fábricas. Se você estiver familiarizado com o padrão de design de fábrica em Java, você notará que temos uma única classe de fábrica que retorna as diferentes subclasses com base na entrada fornecida e a classe de fábrica usa instruções if-else ou switch para conseguir isso. No padrão de fábrica abstrata, nos livramos do bloco if-else e temos uma classe de fábrica para cada subclasse e depois uma classe de fábrica abstrata que retornará a subclasse com base na classe de fábrica de entrada.

Observação: Saiba mais sobre o Padrão de Fábrica Abstrata.

4. Padrão Builder

O padrão builder foi introduzido para resolver alguns dos problemas com os padrões de design de fábrica e fábrica abstrata quando o objeto contém muitos atributos. Este padrão resolve o problema com um grande número de parâmetros opcionais e estado inconsistente, fornecendo uma maneira de construir o objeto passo a passo e fornecer um método que realmente retornará o Object final.

Nota: Saiba mais sobre o Padrão Builder.

5. Padrão Prototype

O padrão de protótipo é usado quando a criação do Object é cara e requer muito tempo e recursos, e você já possui um Object similar existente. Portanto, esse padrão fornece um mecanismo para copiar o Object original para um novo Object e, em seguida, modificá-lo de acordo com nossas necessidades. Este padrão utiliza a clonagem Java para copiar o Object. O padrão de design de protótipo exige que o Object que você está copiando forneça a funcionalidade de cópia. Isso não deve ser feito por nenhuma outra classe. No entanto, a decisão de usar a cópia rasa ou profunda das propriedades do objeto depende dos requisitos e é uma decisão de design.

Nota: Saiba mais sobre o Padrão Prototype.

Padrões de Design Estrutural

Os padrões de design estrutural fornecem diferentes maneiras de criar uma estrutura de Classe (por exemplo, usando herança e composição para criar um Objeto grande a partir de Objetos pequenos).

1. Padrão Adapter

O padrão de design do adaptador é um dos padrões de design estrutural e é usado para que duas interfaces não relacionadas possam trabalhar juntas. O objeto que une essas interfaces não relacionadas é chamado de adaptador.

Nota: Saiba mais sobre o Padrão Adapter.

2. Padrão Composite

O padrão composto é usado quando precisamos representar uma hierarquia parte-todo. Quando precisamos criar uma estrutura de forma que os objetos na estrutura tenham que ser tratados da mesma maneira, podemos aplicar o padrão de design composto.

Nota: Saiba mais sobre o Padrão Composite.

3. Padrão Proxy

O padrão proxy fornece um espaço reservado para outro Objeto controlar o acesso a ele. Este padrão é usado quando queremos fornecer acesso controlado à funcionalidade.

Observação: Saiba mais sobre o Padrão Proxy.

4. Padrão Flyweight

O padrão de design flyweight é usado quando precisamos criar muitos Objetos de uma Classe. Como cada Objeto consome espaço de memória que pode ser crucial para dispositivos de baixa memória (como dispositivos móveis ou sistemas embarcados), o padrão de design flyweight pode ser aplicado para reduzir a carga na memória compartilhando Objetos.

A implementação do pool de strings em Java é um dos melhores exemplos de implementação do padrão flyweight.

Observação: Saiba mais sobre o Padrão Flyweight.

5. Padrão de Fachada

O padrão de fachada é usado para ajudar as aplicações cliente a interagirem facilmente com o sistema.

Nota: Saiba mais sobre o Padrão de Fachada.

6. Padrão de Ponte

Quando temos hierarquias de interface tanto em interfaces quanto em implementações, o padrão de design de ponte é usado para desacoplar as interfaces da implementação e para ocultar os detalhes de implementação dos programas cliente. A implementação do padrão de design de ponte segue a ideia de preferir composição sobre herança.

Nota: Saiba mais sobre o Padrão de Ponte.

7. Padrão de Decorador

O padrão de design decorator é utilizado para modificar a funcionalidade de um objeto em tempo de execução. Ao mesmo tempo, outras instâncias da mesma classe não serão afetadas por isso, garantindo que o comportamento modificado se aplique apenas ao objeto individual. O padrão de design decorator é um dos padrões de design estruturais (como o padrão adaptador, padrão de ponte ou padrão composto) e utiliza classes abstratas ou interfaces com composição para implementação. Enquanto usamos herança ou composição para estender o comportamento de um objeto, isso é feito em tempo de compilação e se aplica a todas as instâncias da classe. Não podemos adicionar nova funcionalidade ou remover qualquer comportamento existente em tempo de execução – é aqui que o padrão decorator se torna útil.

Nota: Saiba mais sobre o Padrão Decorator.

Padrões de Design Comportamentais

Padrões comportamentais oferecem uma solução para uma melhor interação entre objetos e como proporcionar desacoplamento e flexibilidade para extensões fáceis.

1. Padrão de Método de Modelo

O padrão de método de template é um padrão de design comportamental e é usado para criar um esboço de método e adiar algumas etapas de implementação para as subclasses. O método de template define as etapas para executar um algoritmo, e pode fornecer uma implementação padrão que pode ser comum para todas ou algumas das subclasses.

Nota: Saiba mais sobre o Padrão de Método de Template.

2. Padrão de Mediador

O padrão de design do mediador é usado para fornecer um meio de comunicação centralizado entre diferentes objetos em um sistema. Se os objetos interagem diretamente entre si, os componentes do sistema estão fortemente acoplados, o que torna o custo de manutenção mais alto e não flexível para estender facilmente. O padrão do mediador concentra-se em fornecer um mediador entre objetos para comunicação e implementar um acoplamento frouxo entre objetos. O mediador funciona como um roteador entre objetos, e pode ter sua própria lógica para fornecer um meio de comunicação.

Nota: Saiba mais sobre o Padrão de Mediador.

3. Padrão de Chain of Responsibility

O padrão de chain of responsibility é usado para alcançar um desacoplamento flexível no design de software, onde uma solicitação do cliente é passada para uma cadeia de objetos para serem processados. Então, o objeto na cadeia decidirá quem irá processar a solicitação e se a solicitação precisa ser enviada para o próximo objeto na cadeia ou não.

Nós sabemos que podemos ter múltiplos blocos catch em um bloco try-catch de código. Aqui, cada bloco catch é como um processador para processar aquela exceção específica. Então, quando ocorre uma exceção no bloco try, ela é enviada para o primeiro bloco catch para ser processada. Se o bloco catch não for capaz de processá-la, ele encaminha a solicitação para o próximo Object na cadeia (ou seja, o próximo bloco catch). Se nem mesmo o último bloco catch for capaz de processá-la, a exceção é lançada fora da cadeia para o programa chamador.

Observação: Saiba mais sobre o Padrão de Chain of Responsibility.

4. Padrão de Observer

Um padrão de design Observer é útil quando você está interessado no estado de um Object e deseja ser notificado sempre que houver alguma mudança. No padrão Observer, o Object que observa o estado de outro Object é chamado de observador, e o Object que está sendo observado é chamado de sujeito.

O Java fornece uma plataforma integrada para implementar o padrão Observer através da classe java.util.Observable e da interface java.util.Observer. No entanto, não é amplamente utilizado porque a implementação é limitada e na maioria das vezes não queremos acabar estendendo uma classe apenas para implementar o padrão Observer, já que o Java não fornece heranças múltiplas em classes. O Java Message Service (JMS) usa o padrão Observer junto com o padrão mediador para permitir que as aplicações se inscrevam e publiquem dados para outras aplicações.

Nota: Saiba mais sobre o Padrão Observer.

5. Padrão Strategy

O padrão Strategy é usado quando temos vários algoritmos para uma tarefa específica, e o cliente decide qual implementação real será usada em tempo de execução. Um padrão Strategy também é conhecido como padrão de política. Definimos vários algoritmos e permitimos que as aplicações cliente passem o algoritmo a ser usado como parâmetro.

Um dos melhores exemplos desse padrão é o método Collections.sort() que recebe o parâmetro Comparator. Com base nas diferentes implementações das interfaces de comparadores, os objetos são ordenados de maneiras diferentes.

Observação: Saiba mais sobre o Padrão de Estratégia.

6. Padrão de Comando

O padrão de comando é usado para implementar o desacoplamento em um modelo de solicitação-resposta. Nesse padrão, a solicitação é enviada para o invocador e o invocador a passa para o objeto de comando encapsulado. O objeto de comando passa a solicitação para o método apropriado do receptor para realizar a ação específica.

Observação: Saiba mais sobre o Padrão de Comando.

7. Padrão de Estado

O padrão de design de estado é usado quando um Objeto muda seu comportamento com base em seu estado interno. Se precisarmos alterar o comportamento de um Objeto com base em seu estado, podemos ter uma variável de estado no Objeto e usar um bloco de condição if-else para realizar diferentes ações com base no estado. O padrão de estado é usado para fornecer uma maneira sistemática e fracamente acoplada de alcançar isso por meio de implementações de contexto e estado.

Nota: Saiba mais sobre o Padrão de Estado.

8. Padrão de Visitante

O padrão de visitante é usado quando precisamos realizar uma operação em um grupo de objetos semelhantes. Com a ajuda de um padrão de visitante, podemos mover a lógica operacional dos objetos para outra classe.

Nota: Saiba mais sobre o Padrão de Visitante.

9. Padrão de Interpretador

O padrão de interpretador é usado para definir uma representação gramatical de uma linguagem e fornece um interpretador para lidar com essa gramática.

10. Padrão de Iterador

O padrão de iterador é um dos padrões comportamentais e é usado para fornecer uma maneira padrão de percorrer um grupo de objetos. O padrão de iterador é amplamente utilizado no Java Collection Framework onde a interface do iterador fornece métodos para percorrer uma Collection. Este padrão também é usado para fornecer diferentes tipos de iteradores com base em nossos requisitos. O padrão de iterador oculta a implementação real da travessia da Collection e os programas clientes usam os métodos do iterador.

Nota: Saiba mais sobre o Padrão de Iterador.

11. Padrão de Memento

O padrão de design memento é usado quando queremos salvar o estado de um objeto para que possamos restaurá-lo posteriormente. Este padrão é usado para implementar isso de tal forma que os dados de estado salvos do objeto não sejam acessíveis fora do Object, protegendo assim a integridade dos dados de estado salvos.

O padrão Memento é implementado com dois objetos Objectoriginator e caretaker. O originator é o Object cujo estado precisa ser salvo e restaurado, e ele usa uma classe interna para salvar o estado do Object. A classe interna é chamada de “Memento”, e é private para que não possa ser acessada por outros objetos.

Padrões de Design Diversos

Há muitos padrões de design que não se enquadram nos padrões de design do Gang of Four. Vamos dar uma olhada em alguns desses padrões de design populares.

1. Padrão de Design DAO

O padrão de design Data Access Object (DAO) é usado para desacoplar a lógica de persistência de dados para uma camada separada. DAO é um padrão muito popular quando projetamos sistemas para trabalhar com bancos de dados. A ideia é manter a camada de serviço separada da camada de acesso a dados. Dessa forma, implementamos a separação de lógica em nossa aplicação.

Nota: Saiba mais sobre o Padrão DAO.

2. Padrão de Injeção de Dependência

O padrão de injeção de dependência permite-nos remover as dependências codificadas e tornar nossa aplicação com baixo acoplamento, extensível e manutenível. Podemos implementar a injeção de dependência em Java para mover a resolução de dependências do tempo de compilação para o tempo de execução. O framework Spring é construído com base no princípio da injeção de dependência.

Nota: Saiba mais sobre o Padrão de Injeção de Dependência.

3. Padrão MVC

O Padrão Model-View-Controller (MVC) é um dos padrões arquiteturais mais antigos para criar aplicações web.

Conclusão

Este artigo resumiu os padrões de design Java.

Você pode conferir o código de exemplo dos padrões de design Java em nosso Repositório no GitHub.

Continue a sua aprendizagem com mais tutoriais de Java .

Source:
https://www.digitalocean.com/community/tutorials/java-design-patterns-example-tutorial