Padrões de Projeto em C++: Técnicas Avançadas e Exemplos de Código

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Padrões Avançados de Projeto em C++: da Teoria ao Código Real



Padrões de projeto são soluções comprovadas para problemas típicos em programação orientada a objetos. Se você já dominou os padrões básicos (Singleton, Factory, Observer), é hora de avançar para o próximo nível. Neste artigo, vamos analisar quatro padrões avançados: Visitor, Strategy, State e Command. Todos os exemplos são escritos em C++17/20 moderno, usando smart pointers, polimorfismo e templates.



1. Padrão Visitor (Visitante)



O padrão Visitor permite adicionar novas operações a uma hierarquia de classes sem modificar as próprias classes. É uma solução ideal para trabalhar com árvores AST, cenas gráficas ou sistemas de exportação.



Problema

Você tem uma hierarquia de formas geométricas (Circle, Rectangle, Triangle). Precisa implementar operações: cálculo de área, renderização, serialização em JSON. Se adicionar métodos em cada classe, viola o princípio aberto/fechado.



Solução em C++17

#include <iostream>#include <memory>#include <vector>

// Forward declarationclass Circle;class Rectangle;

class Visitor {public: virtual void visit(Circle& c) = 0; virtual void visit(Rectangle& r) = 0; virtual ~Visitor() = default;};

class Shape {public: virtual void accept(Visitor& v) = 0; virtual ~Shape() = default;};

class Circle : public Shape {public: double radius = 5.0; void accept(Visitor& v) override { v.visit(*this); }};

class Rectangle : public Shape {public: double width = 4.0, height = 6.0; void accept(Visitor& v) override { v.visit(*this); }};

// Visitante concretoclass AreaVisitor : public Visitor {public: void visit(Circle& c) override { std::cout << "Circle area: " << 3.14159 * c.radius * c.radius << ""; } void visit(Rectangle& r) override { std::cout << "Rectangle area: " << r.width * r.height << ""; }};

int main() { std::vector<std::unique_ptr<Shape>> shapes; shapes.push_back(std::make_unique<Circle>()); shapes.push_back(std::make_unique<Rectangle>());

AreaVisitor av; for (auto& s : shapes) { s->accept(av); } return 0;}


2. Padrão Strategy (Estratégia)



Strategy permite alterar o algoritmo de processamento de dados durante a execução. Diferente do Visitor, que trabalha com hierarquia de objetos, o Strategy encapsula um algoritmo individual.



Cenário real

Sistema de compressão de arquivos. O usuário escolhe o algoritmo: ZIP, GZIP ou próprio. Em vez de uma cadeia if-else, usamos Strategy.



Implementação com std::function

#include <iostream>#include <functional>#include <string>

class CompressionContext {private: std::function<void(const std::string&)> strategy_;public: explicit CompressionContext(std::function<void(const std::string&)> strategy) : strategy_(std::move(strategy)) {}

void setStrategy(std::function<void(const std::string&)> strategy) { strategy_ = std::move(strategy); }

void compress(const std::string& data) { if (strategy_) { strategy_(data); } else { std::cout << "No strategy set"; } }};

int main() { auto zip = [](const std::string& d) { std::cout << "Compressing with ZIP: " << d << ""; }; auto gzip = [](const std::string& d) { std::cout << "Compressing with GZIP: " << d << ""; };

CompressionContext ctx(zip); ctx.compress("Hello World"); // ZIP

ctx.setStrategy(gzip)

Blogs

Book Recommendations