蔚淦丞
发布于 2026-09-01 / 3 阅读
0
0

结构型设计模式(共 7 种)

1、适配器模式 Adapter

原理:创建适配器中间类,将一个已有类的接口转换成客户端期望的目标接口。让两个原本接口不兼容的类可以一起工作,适配器起到 “转换器” 的作用。 使用场景:接入第三方 SDK、新旧系统模块对接、老代码接口改造。

#include <iostream>
using namespace std;

// 目标接口(客户想要调用的接口)
class Target
{
public:
    virtual void request() = 0;
    virtual ~Target() = default;
};

// 被适配者:旧的、接口不匹配的类
class Adaptee
{
public:
    void oldFunc()
    {
        cout << "旧接口函数执行" << endl;
    }
};

// 适配器:继承目标,内部包装被适配对象
class Adapter : public Target
{
private:
    Adaptee* adaptee;
public:
    Adapter(Adaptee* a) : adaptee(a) {}
    void request() override
    {
        adaptee->oldFunc();
    }
};

int main()
{
    Adaptee oldObj;
    Target* t = new Adapter(&oldObj);
    t->request();
    delete t;
    return 0;
}

一句话归纳:充当转换器,把旧接口转换成目标接口。


2、桥接模式 Bridge

原理:当一个类存在两个可以独立变化的维度,就将抽象部分与实现部分拆分开,二者通过组合而非继承关联;避免多层继承导致子类数量爆炸。 使用场景:图形 + 颜色、跨平台组件、文件格式‑输出设备等二维扩展场景。

#include <iostream>
using namespace std;

// 实现层(变化维度1:颜色)
class Color
{
public:
    virtual void fill() = 0;
    virtual ~Color() = default;
};
class Red : public Color
{
public:
    void fill() override { cout << "红色"; }
};
class Blue : public Color
{
public:
    void fill() override { cout << "蓝色"; }
};

// 抽象层(变化维度2:图形)
class Shape
{
protected:
    Color* color;
public:
    Shape(Color* c) : color(c) {}
    virtual void draw() = 0;
    virtual ~Shape() = default;
};

class Circle : public Shape
{
public:
    Circle(Color* c) : Shape(c) {}
    void draw() override
    {
        cout << "绘制圆形,颜色:";
        color->fill();
        cout << endl;
    }
};

int main()
{
    Color* red = new Red();
    Shape* cir = new Circle(red);
    cir->draw();
    delete cir;
    delete red;
    return 0;
}

一句话归纳:分离抽象与实现,两个维度可独立扩展互不影响。


3、组合模式 Composite

原理:将对象组织成树形层级结构;叶子节点(单个对象)和容器节点(一组对象)对外暴露完全一致的接口,使用者无需区分处理的是单个对象还是集合对象。 使用场景:文件目录树、权限菜单树、组织架构树。

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// 统一抽象组件
class Component
{
public:
    string name;
    Component(string n) : name(n) {}
    virtual void show(int depth) = 0;
    virtual void add(Component*) {}
    virtual ~Component() = default;
};

//叶子节点(文件,不能包含子节点)
class Leaf : public Component
{
public:
    Leaf(string n) : Component(n) {}
    void show(int depth) override
    {
        for (int i = 0; i < depth; i++) cout << "--";
        cout << "文件:" << name << endl;
    }
};

//容器节点(文件夹,可以包含子节点)
class Composite : public Component
{
private:
    vector<Component*> children;
public:
    Composite(string n) : Component(n) {}
    void add(Component* c) override
    {
        children.push_back(c);
    }
    void show(int depth) override
    {
        for (int i = 0; i < depth; i++) cout << "--";
        cout << "文件夹:" << name << endl;
        for (auto child : children)
        {
            child->show(depth + 1);
        }
    }
};

int main()
{
    Composite* root = new Composite("根目录");
    Leaf* file1 = new Leaf("readme.txt");
    root->add(file1);
    root->show(0);
    delete root;
    delete file1;
    return 0;
}

一句话归纳:统一对待单个对象与对象集合,用来构建树形结构。


4、装饰器模式 Decorator

原理:不修改原有对象的代码,动态地一层一层给对象增加额外功能;装饰器类和原始类继承同一个父类,装饰器内部持有原始对象。 使用场景:IO 流包装、报文头部追加、动态添加日志、权限功能。

#include <iostream>
using namespace std;

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

//基础业务对象
class ConcreteComponent : public Component
{
public:
    void operation() override
    {
        cout << "执行基础业务" << endl;
    }
};

//装饰器基类
class Decorator : public Component
{
protected:
    Component* comp;
public:
    Decorator(Component* c) : comp(c) {}
    void operation() override
    {
        comp->operation();
    }
    virtual ~Decorator() = default;
};

//具体装饰:增加日志
class LogDecorator : public Decorator
{
public:
    LogDecorator(Component* c) : Decorator(c) {}
    void operation() override
    {
        cout << "[前置日志] 业务开始" << endl;
        Decorator::operation();
        cout << "[后置日志] 业务结束" << endl;
    }
};

int main()
{
    Component* base = new ConcreteComponent();
    Component* dec = new LogDecorator(base);
    dec->operation();
    delete dec;
    delete base;
    return 0;
}

一句话归纳:动态叠加附加功能,无需修改原对象代码。


5、外观模式 Facade(门面模式)

原理:新增一个高层门面类,内部封装好多个复杂子系统的调用流程;对外只提供一个简单的入口函数,隐藏内部复杂细节。 使用场景:SDK 对外封装、服务启动入口、复杂模块统一调用入口。

#include <iostream>
using namespace std;

//子系统1
class Network
{
public:
    void connect() { cout << "建立网络连接\n"; }
};
//子系统2
class Database
{
public:
    void open() { cout << "打开数据库\n"; }
};
//子系统3
class Logger
{
public:
    void writeLog() { cout << "写入启动日志\n"; }
};

//门面类
class Facade
{
private:
    Network net;
    Database db;
    Logger log;
public:
    void startService()
    {
        net.connect();
        db.open();
        log.writeLog();
        cout << "=== 服务启动成功 ===\n";
    }
};

int main()
{
    Facade facade;
    facade.startService();
    return 0;
}

一句话归纳:为一堆复杂子系统,提供一个简单统一的对外入口。


6、享元模式 Flyweight

原理:使用对象池缓存、复用大量重复对象;对象拆分为内部状态(不变,可共享)、外部状态(可变,调用时传入),以此减少内存中对象数量,节约内存资源。 使用场景:字符池、游戏大量重复粒子对象、连接池。

#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;

//享元对象
class Flyweight
{
public:
    string innerState;
    Flyweight(string s) : innerState(s) {}
    void show(string outerState)
    {
        cout << "共享状态:" << innerState << " ,外部状态:" << outerState << endl;
    }
};

//享元工厂,维护对象池
class FlyweightFactory
{
private:
    unordered_map<string, Flyweight*> pool;
public:
    Flyweight* getFlyweight(string key)
    {
        if (pool.find(key) == pool.end())
        {
            pool[key] = new Flyweight(key);
        }
        return pool[key];
    }
};

int main()
{
    FlyweightFactory factory;
    Flyweight* f1 = factory.getFlyweight("A");
    Flyweight* f2 = factory.getFlyweight("A");

    f1->show("第一次调用");
    f2->show("第二次调用");
    cout << f1 << " " << f2 << endl; //地址完全相同,复用同一个对象
    return 0;
}

一句话归纳:共享重复对象,降低大量对象带来的内存开销。


7、代理模式 Proxy

原理:创建一个代理对象,代理和真实对象实现同一个接口;客户端访问代理对象,再由代理去调用真实对象,可在前后增加鉴权、日志、缓存、延时加载等附加逻辑。 使用场景:RPC 远程代理、接口权限校验、大对象延迟加载。

#include <iostream>
using namespace std;

//公共抽象接口
class Subject
{
public:
    virtual void request() = 0;
    virtual ~Subject() = default;
};

//真实对象
class RealSubject : public Subject
{
public:
    void request() override
    {
        cout << "真实对象执行业务逻辑" << endl;
    }
};

//代理对象
class Proxy : public Subject
{
private:
    RealSubject* realObj;
public:
    Proxy()
    {
        realObj = new RealSubject();
    }
    void request() override
    {
        cout << "代理:前置权限校验\n";
        realObj->request();
        cout << "代理:后置记录调用日志\n";
    }
    ~Proxy()
    {
        delete realObj;
    }
};

int main()
{
    Proxy proxy;
    proxy.request();
    return 0;
}

一句话归纳:通过代理对象控制对真实对象的访问。


评论