Patrones de diseño en C++: técnicas avanzadas y ejemplos de código

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Patrones de diseño avanzados en C++: de la teoría al código real



Los patrones de diseño son soluciones probadas para problemas típicos en la programación orientada a objetos. Si ya dominas los patrones básicos (Singleton, Factory, Observer), es hora de pasar al siguiente nivel. En este artículo analizaremos cuatro patrones avanzados: Visitor, Strategy, State y Command. Todos los ejemplos están escritos en C++17/20 moderno usando punteros inteligentes, polimorfismo y plantillas.



1. Patrón Visitor (Visitante)



El patrón Visitor permite agregar nuevas operaciones a una jerarquía de clases sin modificar las clases mismas. Es una solución ideal para trabajar con árboles AST, escenas gráficas o sistemas de exportación.



Problema

Tienes una jerarquía de figuras geométricas (Circle, Rectangle, Triangle). Necesitas implementar operaciones: cálculo de área, dibujo, serialización a JSON. Si agregas métodos en cada clase, se viola el principio de abierto/cerrado.



Solución en 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. Patrón Strategy (Estrategia)



Strategy permite cambiar el algoritmo de procesamiento de datos durante la ejecución. A diferencia de Visitor, que trabaja con una jerarquía de objetos, Strategy encapsula un algoritmo individual.



Escenario real

Sistema de compresión de archivos. El usuario selecciona un algoritmo: ZIP, GZIP o propio. En lugar de una cadena if-else, usamos Strategy.



Implementación con 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