Introdução aos Padrões de Projeto
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 90 de 104.
Padrões de projeto são soluções comprovadas e reutilizáveis para problemas comuns que surgem no projeto de software. Eles não são códigos que você copia diretamente — são modelos ou projetos que descrevem como estruturar classes e objetos para resolver desafios específicos de maneira elegante.
O conceito foi popularizado pela "Gang of Four" (GoF) em seu livro de 1994, que catalogou 23 padrões fundamentais. Esses padrões normalmente são agrupados em três categorias:
| Categoria | Finalidade | Exemplos |
|---|---|---|
| Creational | Mecanismos de criação de objetos | Singleton, Factory, Builder |
| Structural | Composição de classes e objetos | Adapter, Decorator, Composite |
| Behavioral | Interação e responsabilidades dos objetos | Observer, Strategy, Command |
Por que aprender padrões de projeto? Eles fornecem um vocabulário compartilhado entre os desenvolvedores — dizer "use uma Factory aqui" comunica instantaneamente uma ideia complexa. Eles também ajudam você a evitar reinventar soluções e tornam seu código mais flexível e fácil de manter.
Em C++, os padrões de projeto aproveitam os recursos de OOP que você já aprendeu: herança, polimorfismo, classes abstratas e templates. Nas próximas lições, você implementará vários padrões essenciais e entenderá quando cada um é a ferramenta certa para o trabalho.
Desafio
FácilVamos criar um classificador simples de padrões que demonstre sua compreensão das três categorias de padrões de projeto. Você criará um sistema que recebe o nome de um padrão e identifica a qual categoria ele pertence — Creational, Structural ou Behavioral — juntamente com uma breve descrição da finalidade dessa categoria.
Você organizará seu código em três arquivos:
PatternCategory.h: defina uma classe base abstrata chamadaPatternCategoryque represente uma categoria de padrão de projeto. Ela deve ter:- Um método virtual puro
getName()que retorne o nome da categoria como uma string - Um método virtual puro
getPurpose()que retorne uma descrição do que os padrões nessa categoria fazem - Um destrutor virtual
Em seguida, crie três classes derivadas que herdem de
PatternCategory:CreationalCategory: retorna o nome"Creational"e a finalidade"Object creation mechanisms"StructuralCategory: retorna o nome"Structural"e a finalidade"Class and object composition"BehavioralCategory: retorna o nome"Behavioral"e a finalidade"Object interaction and responsibility"
- Um método virtual puro
PatternClassifier.h: crie uma classePatternClassifierque possa identificar a qual categoria pertence um determinado padrão.Seu classificador deve ter um método
classifyque receba o nome de um padrão (string) e retorne um ponteiro para oPatternCategoryapropriado. Use ponteiros inteligentes (std::unique_ptr) para o gerenciamento de memória.O classificador deve reconhecer estes padrões:
- Creational:
Singleton,Factory,Builder - Structural:
Adapter,Decorator,Composite - Behavioral:
Observer,Strategy,Command
Se o nome do padrão não for reconhecido, retorne
nullptr.- Creational:
main.cpp: leia uma única entrada: o nome de um padrão de projeto.Crie um
PatternClassifiere use-o para classificar o padrão informado. Se o padrão for reconhecido, imprima:[PatternName] is a [CategoryName] pattern Purpose: [CategoryPurpose]Se o padrão não for reconhecido, imprima:
Unknown pattern: [PatternName]
Por exemplo, com a entrada Singleton:
Singleton is a Creational pattern
Purpose: Object creation mechanismsCom a entrada Observer:
Observer is a Behavioral pattern
Purpose: Object interaction and responsibilityCom a entrada Proxy:
Unknown pattern: ProxyEste desafio reforça as três categorias de padrões de projeto enquanto pratica herança, polimorfismo e ponteiros inteligentes: todos conceitos que você já dominou. A estrutura em vários arquivos reproduz a forma como projetos reais organizam classes relacionadas.
Experimente você mesmo
#include <iostream>
#include <string>
#include "PatternClassifier.h"
int main() {
// Leia o nome do padrão
std::string patternName;
std::cin >> patternName;
// TODO: Crie uma instância de PatternClassifier
// TODO: Use o classificador para classificar o padrão de entrada
// TODO: Se o padrão for reconhecido, imprima:
// "[PatternName] is a [CategoryName] pattern"
// "Purpose: [CategoryPurpose]"
// TODO: Se o padrão não for reconhecido (nullptr), imprima:
// "Unknown pattern: [PatternName]"
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos externosBuild e compilação em C++Arquivos de cabeçalho e arquivos-fonteNamespaces e escopoIntrodução à POO em C++Classes vs. objetosO ponteiro 'this'Métodos (funções membro)Atributos (membros de dados)Noções básicas de construtores e destruidoresRevisão - calculadora simples4Propriedades de Classe
Membros de Instância vs. EstáticosGetters e SettersFunções Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRevisão - Gerenciador de Contas Bancárias7Herança
Herança básicaNíveis de acesso da herançaOrdem de chamada de construtor e destrutorSobrescrita de métodosFunções virtuais e VTableHerança múltiplaHerança virtualRevisão - Hierarquia de funcionários10Visão geral da STL
Visão geral e filosofia da STLContêineres da STLIteradoresAlgoritmos da STLFunctors e expressões lambdaRecapitulação - Frequência de palavras13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonFactory e Abstract FactoryPadrão BuilderPadrão ObserverPadrão Strategy2Gerenciamento de Memória
Memória Stack vs. HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Ponteiros Inteligentes em C++RAII em C++Revisão - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de acesso em C++Especificadores de acesso em profundidadeOcultação de informaçõesStruct vs ClasseClasses aninhadas e internasRecapitulação - Sistema de registros de alunos8Polimorfismo
Polimorfismo em compilação vs. execuçãoSobrecarga de funçõesFunções virtuais revisadasFunções virtuais purasClasses abstratasDesign de interfaces em C++Conversão dinâmica e RTTIRecapitulação — Calculadora de formas11Conceitos Avançados de OOP
Composição vs. HerançaMixins via CRTPIdioma PimplApagamento de TiposClasses Enum e Tipagem ForteTratamento de Exceções em OOPHierarquias de Exceções Personalizadas14Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositeRAII como Padrão3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentoListas de Inicialização do ConstrutorConstrutores DelegantesAprofundamento em DestrutoresRegra dos Três / Cinco / ZeroRevisão - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de FluxoSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçõesTemplates de ClassesEspecialização de TemplatesTemplates VariádicosNoções Básicas de SFINAE e Traits de TiposRecapitulação - Contêiner GenéricoPratique por conta própria: Compilador de C++ online