Olá, querida(o) estudante! Neste artigo, vamos explorar os Padrões de Projeto (Design Patterns), um dos conceitos mais importantes no desenvolvimento de software moderno. Esses padrões fornecem soluções para problemas comuns de design que surgem durante a construção de sistemas, facilitando o desenvolvimento, a manutenção e a escalabilidade dos projetos. Vamos entender melhor como os padrões de projeto funcionam e suas principais categorias!
O que são Padrões de Projeto?
Padrões de Projeto são soluções reutilizáveis para problemas comuns que ocorrem no desenvolvimento de software. Eles não são soluções prontas, mas sim guias que ajudam a estruturar o código de maneira mais eficiente. Esses padrões podem ser classificados em três grandes categorias: Padrões Criacionais, Padrões Estruturais e Padrões Comportamentais.
História dos Padrões de Projeto
Os padrões de projeto se tornaram amplamente conhecidos a partir do livro “Design Patterns: Elements of Reusable Object-Oriented Software”, publicado em 1994 por Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides, conhecidos como a Gang of Four (GoF). Antes disso, as soluções para problemas de design de software eram discutidas de maneira informal entre os desenvolvedores. A Gang of Four organizou essas soluções em um conjunto de 23 padrões que são amplamente utilizados até hoje. Esses padrões ajudam a resolver problemas de design recorrentes de maneira eficiente e flexível, promovendo a reutilização de código e boas práticas de programação.
Padrões Criacionais
Os padrões criacionais abstraem o processo de criação de objetos, permitindo flexibilidade e controle no processo de instanciamento. Eles ajudam a desacoplar o código que usa objetos do código que cria objetos, permitindo maior reutilização e escalabilidade.
- Abstract Factory
O que faz: Fornece uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.
Exemplo: Imagine um sistema de interface gráfica que deve funcionar tanto em Windows quanto em macOS. Cada sistema operacional possui seu próprio conjunto de componentes (botões, menus, janelas). O Abstract Factory permite criar objetos compatíveis com o sistema em questão sem precisar alterar o código cliente. - Builder
O que faz: Separa a construção de um objeto complexo da sua representação, permitindo que o mesmo processo de construção crie diferentes representações.
Exemplo: A criação de uma casa com diferentes partes como portas, janelas e telhados. O Builder permite construir casas de diferentes tipos (casa de madeira, de concreto, etc.) sem alterar o processo geral de construção. - Factory Method
O que faz: Define uma interface para criar objetos, mas deixa que as subclasses decidam qual classe instanciar.
Exemplo: Em um jogo, você pode ter diferentes tipos de personagens (guerreiro, mago, arqueiro). O Factory Method permite que cada tipo de personagem seja criado dinamicamente com base na escolha do jogador, sem que o código principal precise conhecer os detalhes de criação de cada personagem. - Prototype
O que faz: Cria novos objetos copiando uma instância já existente (protótipo), evitando a criação direta de novos objetos.
Exemplo: Imagine um editor gráfico onde formas geométricas (círculos, quadrados, etc.) são frequentemente reutilizadas. O padrão Prototype permite duplicar essas formas sem precisar recriar cada uma do zero. - Singleton
O que faz: Garante que uma classe tenha apenas uma instância ao longo de toda a aplicação e fornece um ponto de acesso global a essa instância.
Exemplo: Um sistema de gerenciamento de logs pode usar o Singleton para garantir que todos os componentes do sistema escrevam os logs em um único arquivo compartilhado.
Padrões Estruturais
Os padrões estruturais lidam com a composição de classes e objetos para formar estruturas maiores. Eles ajudam a organizar os componentes do sistema, tornando a interação entre eles mais eficiente.
- Adapter
O que faz: Permite que interfaces incompatíveis trabalhem juntas, convertendo a interface de uma classe em outra esperada pelo cliente.
Exemplo: Suponha que você tem uma aplicação que precisa exibir dados em um formato legado, mas a nova API fornece os dados em um formato diferente. O Adapter permite que você use a nova API sem alterar o código legado. - Bridge
O que faz: Separa a abstração da implementação, permitindo que ambos variem independentemente.
Exemplo: Em um sistema de janelas, você pode ter várias implementações de renderização (Windows, macOS, Linux) e várias abstrações de janelas (simples, modais, etc.). O Bridge permite combinar qualquer abstração com qualquer implementação sem que uma dependa diretamente da outra. - Composite
O que faz: Composição de objetos em estruturas de árvore para representar hierarquias parte-todo. Permite que clientes tratem objetos individuais e composições de objetos de maneira uniforme.
Exemplo: Em um editor gráfico, você pode ter formas simples como círculos e retângulos, mas também grupos de formas que se comportam como um único objeto. O Composite permite tratar essas formas e grupos de maneira consistente. - Decorator
O que faz: Anexa responsabilidades adicionais a um objeto de maneira dinâmica, oferecendo uma alternativa flexível à criação de subclasses para estender funcionalidades.
Exemplo: Em um sistema de notificação, o objeto principal pode enviar notificações por e-mail. Usando o padrão Decorator, você pode adicionar funcionalidades como envio de SMS ou push notification sem modificar o código base do sistema de e-mails. - Facade
O que faz: Fornece uma interface simplificada para um subsistema complexo, tornando seu uso mais fácil.
Exemplo: Em um sistema de home theater, o Facade pode fornecer uma interface única para ligar a TV, ajustar o som, e tocar um filme, sem que o cliente precise interagir diretamente com todos esses componentes individualmente. - Flyweight
O que faz: Usa o compartilhamento para suportar grandes quantidades de objetos granulares de forma eficiente, minimizando o uso de memória.
Exemplo: Em um jogo de estratégia, há milhares de árvores no mapa. Ao invés de criar um objeto para cada árvore, o Flyweight compartilha as informações comuns entre as árvores (como textura e cor) e cria objetos individuais apenas para as informações variáveis (como posição). - Proxy
O que faz: Fornece um substituto ou placeholder para outro objeto para controlar o acesso a ele, adicionando funcionalidades como controle de acesso, cache, ou log.
Exemplo: Um Proxy de segurança pode verificar as permissões de um usuário antes de permitir o acesso a um objeto sensível, como dados financeiros.
Padrões Comportamentais
Os padrões comportamentais se concentram na interação entre objetos e na forma como eles comunicam e trocam responsabilidades, promovendo a flexibilidade e desacoplamento entre eles.
- Chain of Responsibility
O que faz: Passa uma solicitação ao longo de uma cadeia de manipuladores, onde cada manipulador decide se processa a solicitação ou passa adiante.
Exemplo: Em um sistema de atendimento ao cliente, uma solicitação pode passar por diferentes níveis de suporte (nível 1, nível 2, supervisor) até que seja resolvida. Cada nível decide se pode resolver ou se deve passar a solicitação adiante. - Command
O que faz: Encapsula uma solicitação como um objeto, permitindo que você parametrize clientes com diferentes solicitações, enfileire ou registre solicitações e suporte operações que podem ser desfeitas.
Exemplo: Em um editor de texto, cada ação (como digitar, deletar, formatar) pode ser encapsulada como um comando, permitindo desfazer e refazer essas operações. - Interpreter
O que faz: Dado um idioma, define uma representação para sua gramática e um interpretador que usa essa representação para interpretar sentenças no idioma.
Exemplo: Em calculadoras ou linguagens de script, o Interpreter pode ser usado para interpretar e executar expressões matemáticas ou comandos. - Iterator
O que faz: Fornece uma maneira de acessar sequencialmente os elementos de um agregado sem expor sua representação subjacente.
Exemplo: Em uma lista de objetos, o Iterator permite percorrer os elementos de maneira uniforme, sem que o cliente precise saber como a lista é implementada (array, linked list, etc.). - Mediator
O que faz: Define um objeto que encapsula como um conjunto de objetos interage, promovendo o desacoplamento direto entre os objetos.
Exemplo: Em um sistema de chat, o Mediator pode gerenciar a comunicação entre vários usuários, permitindo que eles se comuniquem sem precisar saber diretamente uns dos outros. - Memento
O que faz: Captura e externaliza o estado interno de um objeto sem violar o encapsulamento, permitindo que o objeto seja restaurado a esse estado mais tarde.
Exemplo: Em um editor de texto, o Memento pode ser usado para salvar o estado de um documento, permitindo que o usuário volte a versões anteriores sem expor os detalhes internos do editor. - Observer
O que faz: Define uma dependência um-para-muitos entre objetos para que quando um objeto mude de estado, todos os seus dependentes sejam notificados e atualizados automaticamente.
Exemplo: Em um sistema de notificações de redes sociais, quando um usuário posta uma nova foto, todos os seus seguidores são notificados automaticamente. - State
O que faz: Permite que um objeto altere seu comportamento quando seu estado interno muda. O objeto parecerá ter mudado de classe.
Exemplo: Em uma máquina de vendas automáticas, o comportamento muda dependendo do estado (sem moedas, com moedas, item selecionado, item esgotado). - Strategy
O que faz: Define uma família de algoritmos, encapsula cada um deles e os torna intercambiáveis. Permite que o algoritmo varie independentemente dos clientes que o utilizam.
Exemplo: Um sistema de pagamento online pode usar diferentes estratégias de pagamento (cartão de crédito, PayPal, boleto), permitindo que o cliente escolha qual usar sem que o sistema precise conhecer os detalhes de cada estratégia. - Template Method
O que faz: Define o esqueleto de um algoritmo em uma operação, deixando que as subclasses implementem alguns passos sem mudar a estrutura geral do algoritmo.
Exemplo: Em um sistema de processamento de pedidos, o método geral pode incluir etapas como validação, cálculo de preço e envio, mas a implementação de cada etapa pode variar de acordo com o tipo de pedido (pedido físico ou digital). - Visitor
O que faz: Representa uma operação a ser executada em elementos de uma estrutura de objetos, permitindo que você defina uma nova operação sem mudar as classes dos elementos sobre os quais opera.
Exemplo: Em um sistema de análise de arquivos, o Visitor pode ser usado para aplicar diferentes operações a diferentes tipos de arquivos (texto, imagem, vídeo), sem modificar as classes de arquivo.
Referência:
- Padrões de Projeto: Soluções Reutilizáveis de Software Orientado a Objetos. Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (2000).
Vamos ver como esse assunto é cobrado nos concursos!
1) Ano: 2023 Banca: Instituto Consulplan Órgão: IF-PA Prova: Instituto Consulplan – 2023 – IF-PA – Técnico de Tecnologia da Informação
O uso de padrões de projetos tem vantagens relacionadas ao desenvolvimento de software, aumentando a produtividade e a qualidade e facilitando a lógica de programação e o tempo de desenvolvimento. Sobre as características dos padrões de projeto orientados a objetos, analise as afirmativas a seguir.
I. Projetar software reutilizável orientado a objetos é uma tarefa complexa.
II. Projetistas, quando encontram uma solução, reutilizam-na várias vezes.
III. Bons projetistas sabem que devem resolver problemas de software a partir do zero.
IV. Padrões de projeto conseguem resolver problemas específicos e complexos. Está correto o que se afirma apenas em
Alternativas
a) II e III.
b) II e IV.
c) I, II e IV.
d) I, III e IV.
Gabarito: C
Comentário:
I. Correto. Criar software reutilizável e bem estruturado em um ambiente orientado a objetos é uma tarefa difícil. A complexidade está em criar soluções flexíveis e escaláveis, sem criar dependências rígidas entre componentes. Padrões de projeto ajudam a aliviar essa complexidade ao fornecer soluções testadas para problemas recorrentes.
II. Correto. Esta afirmativa reflete a essência dos padrões de projeto. Padrões são soluções que os projetistas identificam e utilizam repetidamente em diferentes contextos para resolver problemas semelhantes. Isso permite maior consistência e eficiência no desenvolvimento de software.
II. Incorreto. Esta afirmativa está incorreta, pois contraria a filosofia dos padrões de projeto. Bons projetistas reconhecem que reinventar a roda é desnecessário e, em vez disso, procuram soluções já existentes que foram testadas e otimizadas. Um dos principais objetivos dos padrões de projeto é evitar a necessidade de resolver problemas do zero sempre que surgem.
IV. Correto. Padrões de projeto oferecem soluções claras para problemas complexos e recorrentes no desenvolvimento de software. Eles ajudam a lidar com questões como flexibilidade, escalabilidade e manutenção, fornecendo um guia de como estruturar o código para resolver esses desafios de maneira eficiente.
2) Ano: 2024 Banca: IBFC Órgão: TRF – 5ª REGIÃO Prova: IBFC – 2024 – TRF – 5ª REGIÃO – Técnico Judiciário – Área de Apoio Especializado – Especialidade Desenvolvimento de Sistemas da Informação
Analise as afirmativas abaixo sobre padrões de projeto e dê valores Verdadeiro (V) ou Falso (F).
( ) Padrões de projeto são soluções comprovadas para problemas recorrentes no design de software, promovendo boas práticas e reutilização de código.
( ) O padrão Observer é utilizado para definir uma dependência um-para-muitos entre objetos, de modo que, quando um objeto muda de estado, todos os seus dependentes são notificados e atualizados automaticamente.
( ) Padrões de projeto podem ser classificados em três categorias principais: padrões de criação, padrões estruturais e padrões comportamentais.
Assinale a alternativa que apresenta a sequência correta de cima para baixo.
a) V – F – F
b) F – F – V
c) F – V – F
d) V – V – V
Gabarito: D
Comentário:
- Correto. Padrões de projeto são soluções testadas e amplamente aceitas para resolver problemas comuns no design de software. Eles promovem boas práticas de programação, como reutilização de código, modularidade e manutenção mais fácil.
- Correto. O padrão Observer é um padrão comportamental que permite que um objeto (o “observado”) notifique automaticamente todos os objetos dependentes (os “observadores”) quando seu estado muda. Um exemplo clássico é o sistema de notificação de redes sociais, onde seguidores são notificados quando o perfil que eles seguem faz uma nova postagem.
- Correto. Os padrões de projeto são tradicionalmente divididos em três categorias:
- Padrões Criacionais (relacionados à criação de objetos),
- Padrões Estruturais (relacionados à composição de classes e objetos),
- Padrões Comportamentais (relacionados à interação entre objetos).
É isso para o artigo de hoje!
Te desejo bons estudos e nos vemos no nosso próximo encontro 🙂
Prof. Ana Júlia B. de Souza
Quer ficar por dentro dos concursos públicos abertos e previstos pelo Brasil? Clique nos links abaixo:
Receba gratuitamente no seu celular as principais notícias do mundo dos concursos. Clique no link abaixo e inscreva-se:
Participe da conversa