CppStack

C++技术栈一站式学习 · ‌业精于勤,荒于嬉;行成于思,毁于随。

C++ 设计模式详解(二):结构型模式

Tags = [ C++Pattern ]

结构型模式(Structural Patterns)关注 类和对象的组合,通过合理的结构组织,提升系统的 灵活性、可扩展性和复用性
常见的结构型模式包括:

  1. 适配器(Adapter)
  2. 装饰器(Decorator)
  3. 代理(Proxy)
  4. 外观(Facade)
  5. 桥接(Bridge)
  6. 组合(Composite)
  7. 享元(Flyweight)

结构型模式详解


1. 适配器模式(Adapter)

定义:将一个类的接口转换成客户期望的另一个接口,使原本不兼容的类可以协同工作。
场景

  • 新旧系统兼容(如新接口调用旧库)。
  • 第三方库接口与现有系统不一致。
#include <iostream>

// 旧接口
class OldPrinter {
public:
    void oldPrint() { std::cout << "Old Printer\n"; }
};

// 新接口
class IPrinter {
public:
    virtual void print() = 0;
    virtual ~IPrinter() = default;
};

// 适配器
class Adapter : public IPrinter {
    OldPrinter* old;
public:
    Adapter(OldPrinter* o):old(o){}
    void print() override { old->oldPrint(); }
};

int main() {
    OldPrinter old;
    Adapter a(&old);
    a.print(); // 通过新接口调用旧方法
}

2. 装饰器模式(Decorator)

定义:动态地给对象添加额外的职责,而不改变其接口。
场景

  • 在不修改类的情况下扩展功能。
  • GUI 组件(如给窗口添加滚动条、边框)。
#include <iostream>
#include <memory>

class Component {
public:
    virtual void operation() = 0;
    virtual ~Component() = default;
};

class ConcreteComponent : public Component {
public:
    void operation() override { std::cout << "Base operation\n"; }
};

class Decorator : public Component {
protected:
    std::unique_ptr<Component> comp;
public:
    Decorator(std::unique_ptr<Component> c):comp(std::move(c)){}
};

class ConcreteDecorator : public Decorator {
public:
    using Decorator::Decorator;
    void operation() override {
        comp->operation();
        std::cout << " + Extra feature\n";
    }
};

int main() {
    std::unique_ptr<Component> c = std::make_unique<ConcreteComponent>();
    std::unique_ptr<Component> d = std::make_unique<ConcreteDecorator>(std::move(c));
    d->operation();
}

3. 代理模式(Proxy)

定义:为其他对象提供一个代理以控制对它的访问。
场景

  • 远程代理(RPC)。
  • 虚拟代理(延迟加载大对象)。
  • 保护代理(权限控制)。
#include <iostream>
#include <memory>

class Subject {
public:
    virtual void request() = 0;
    virtual ~Subject() = default;
};

class RealSubject : public Subject {
public:
    void request() override { std::cout << "Real request\n"; }
};

class Proxy : public Subject {
    std::unique_ptr<RealSubject> real;
public:
    void request() override {
        if (!real) real = std::make_unique<RealSubject>();
        std::cout << "Proxy check\n";
        real->request();
    }
};

int main() {
    Proxy p;
    p.request();
}

4. 外观模式(Facade)

定义:为子系统中的一组接口提供一个统一的高层接口,使子系统更易使用。
场景

  • 简化复杂系统的使用。
  • 提供统一入口(如编译器子系统)。
#include <iostream>

class CPU { public: void run(){ std::cout << "CPU running\n"; } };
class Memory { public: void load(){ std::cout << "Memory loading\n"; } };
class Disk { public: void read(){ std::cout << "Disk reading\n"; } };

class Computer {
    CPU cpu; Memory mem; Disk disk;
public:
    void start() {
        cpu.run();
        mem.load();
        disk.read();
        std::cout << "Computer started\n";
    }
};

int main() {
    Computer c;
    c.start();
}

5. 桥接模式(Bridge)

定义:将抽象部分与实现部分分离,使它们可以独立变化。
场景

  • 多维度变化(如图形形状 + 渲染方式)。
  • 避免类爆炸。
#include <iostream>
#include <memory>

class Renderer {
public:
    virtual void renderCircle(float r) = 0;
    virtual ~Renderer() = default;
};

class VectorRenderer : public Renderer {
public:
    void renderCircle(float r) override { std::cout << "Vector circle r="<<r<<"\n"; }
};

class RasterRenderer : public Renderer {
public:
    void renderCircle(float r) override { std::cout << "Raster circle r="<<r<<"\n"; }
};

class Shape {
protected:
    std::shared_ptr<Renderer> renderer;
public:
    Shape(std::shared_ptr<Renderer> r):renderer(r){}
    virtual void draw() = 0;
};

class Circle : public Shape {
    float radius;
public:
    Circle(std::shared_ptr<Renderer> r,float rad):Shape(r),radius(rad){}
    void draw() override { renderer->renderCircle(radius); }
};

int main() {
    auto r = std::make_shared<VectorRenderer>();
    Circle c(r,5);
    c.draw();
}

6. 组合模式(Composite)

定义:将对象组合成树形结构以表示“部分-整体”的层次结构。
场景

  • 文件系统(文件和文件夹)。
  • GUI 组件树。
#include <iostream>
#include <vector>
#include <memory>

class Component {
public:
    virtual void operation() = 0;
    virtual ~Component() = default;
};

class Leaf : public Component {
public:
    void operation() override { std::cout << "Leaf\n"; }
};

class Composite : public Component {
    std::vector<std::unique_ptr<Component>> children;
public:
    void add(std::unique_ptr<Component> c){ children.push_back(std::move(c)); }
    void operation() override {
        std::cout << "Composite\n";
        for(auto& c:children) c->operation();
    }
};

int main() {
    auto root = std::make_unique<Composite>();
    root->add(std::make_unique<Leaf>());
    auto branch = std::make_unique<Composite>();
    branch->add(std::make_unique<Leaf>());
    root->add(std::move(branch));
    root->operation();
}

7. 享元模式(Flyweight)

定义:运用共享技术有效地支持大量细粒度对象。
场景

  • 游戏中大量相似对象(如树、子弹)。
  • 文本编辑器中的字符对象。
#include <iostream>
#include <map>
#include <memory>

class Flyweight {
    char symbol;
public:
    Flyweight(char c):symbol(c){}
    void draw(int x,int y){ std::cout << "Draw "<<symbol<<" at "<<x<<","<<y<<"\n"; }
};

class FlyweightFactory {
    std::map<char,std::shared_ptr<Flyweight>> pool;
public:
    std::shared_ptr<Flyweight> get(char c){
        if(!pool.count(c)) pool[c]=std::make_shared<Flyweight>(c);
        return pool[c];
    }
};

int main() {
    FlyweightFactory f;
    auto a = f.get('A');
    auto b = f.get('A');
    a->draw(1,2);
    b->draw(3,4);
    std::cout << (a==b); // 共享对象
}

总结

  • 适配器:接口兼容。
  • 装饰器:动态扩展功能。
  • 代理:控制访问。
  • 外观:简化接口。
  • 桥接:分离抽象与实现。
  • 组合:树形结构。
  • 享元:共享对象,节省内存。

结构型模式的核心是 通过合理的对象组合,提升系统的灵活性和复用性