Padrões de Projeto: Guia para Desenvolvedores
Classificado em Computação
Escrito em em português com um tamanho de 5,64 KB.
Padrões de Projeto: O Que São e Por Que Usar?
Padrões de projeto existem para evitar reinventar algo que já foi inventado, para melhorar a qualidade do software, a sua documentação e facilitar a comunicação geral. Eles não definem soluções exatas, não resolvem todos os problemas de design e não são exclusivos de Orientação a Objetos (OO).
Características dos Padrões de Projeto
- Encapsulamento: Deve encapsular um problema ou uma solução bem definida e específica, deve ser independente do restante do software e sua aplicação deve ser clara.
- Generalidade: Deve permitir a construção de outras implementações.
- Equilíbrio: Deve haver uma razão para utilizar o padrão (restrição, análise abstrata, observação, exemplos e soluções boas e ruins).
- Abstração: Deve representar uma abstração do conhecimento existente no cotidiano.
- Abertura: Deve permitir a extensão para níveis mais baixos de detalhes.
- Combinatoriedade: Deve relacionar-se hierarquicamente; os de alto nível podem ser compostos ou relacionados com padrões de baixo nível.
Classificação dos Padrões de Projeto
Por propósito:
- 5 padrões de criação: Relacionados à criação de objetos.
- 7 padrões estruturais: Tratam das associações entre classes e objetos.
- 11 padrões comportamentais: Tratam das interações e divisões de responsabilidades entre classes e objetos.
Por escopo:
- Padrões de classes: Tratam das relações entre classes e subclasses, são estáticos e definidos em tempo de compilação.
- Padrões de objeto: Tratam das relações entre objetos, podem mudar em tempo de execução.
Padrões de Criação
Abstract Factory
Proporciona uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas. (Dica: enfatiza famílias de objetos).
Quando usar: Quando o sistema deve ser configurado com uma de múltiplas famílias de produtos, e estes são projetados para serem utilizados juntos para garantir a restrição.
Exemplo: Montar uma interface gráfica para vários sistemas operacionais.
Builder
Separa a construção de um objeto complexo da sua representação, criando diferentes tipos de representações no mesmo processo.
Quando usar: Quando o algoritmo deve ser independente de suas partes e de como serão montadas. (Dica: constrói partes de objetos passo a passo).
Exemplo: Sistema de produção automatizado de pizzas.
Factory Method
Define a interface para criar um objeto, mas deixa as subclasses decidirem qual classe instanciar.
Quando usar: Quando uma classe não pode antecipar a classe de objetos que ela deve criar ou quando uma classe quer que suas subclasses especifiquem os objetos que ela cria.
Exemplo: Escolha de sexo durante a execução do programa, com resultados distintos para cada gênero.
Prototype
Especifica os tipos de objetos para criar usando um protótipo e cria novos objetos copiando esse protótipo.
Quando usar: Quando os componentes possuem um estado inicial que tem poucas variações, e é conveniente disponibilizar um conjunto preestabelecido de protótipos que dão origem aos objetos.
Singleton
Garante que uma classe tenha apenas uma instância, provendo um ponto de acesso global a ela.
Quando usar: Quando deve haver uma única instância de uma classe, devendo ser acessível aos clientes por um ponto de acesso conhecido.
Exemplo: Jobs de impressão, mas um spooler para enfileirar as impressões.
Padrões Estruturais
Adapter
Converte a interface de uma classe em outra interface, permitindo que classes que não poderiam trabalhar juntas passem a fazê-lo.
Quando usar: Quando a interface existente não é adequada à classe que você precisa.
Exemplo: Adaptar uma API de terceiro em um software já implementado.
Bridge
Desacopla uma interface de sua implementação para que possam variar de forma independente.
Quando usar: Para evitar um vínculo entre abstração e implementação, e quando mudanças na implementação não devem ter impacto nos clientes.
Exemplo: API de desenho gráfico.
Composite
Compõe zero ou mais objetos similares de forma que sejam manipulados como um só.
Quando usar: Quando se quer que o cliente ignore a diferença entre objetos compostos e individuais.
Exemplo: Árvores.
Decorator
Anexa responsabilidades adicionais a um objeto dinamicamente, fornecendo uma alternativa em relação à herança para estender funcionalidades.
Quando usar: Para adicionar responsabilidades a objetos dinamicamente ou quando a extensão por subclasses é impraticável.
Exemplo: API Gráfica com muitas variações de objetos.