详解23种设计模式

设计模式(Design Patterns)一般分为三大类:创建型模式结构型模式行为型模式

1. 创建型模式(Creational Patterns)

这些模式主要关注对象的创建过程,目的是通过控制对象的创建,来避免复杂性并提升灵活性。

1.1 单例模式(Singleton)
  • 定义:确保一个类只有一个实例,并提供一个全局访问点。
  • 使用场景:需要一个全局唯一的对象时,如配置类、日志管理类。
1.2 工厂方法模式(Factory Method)
  • 定义:定义一个用于创建对象的接口,但由子类决定实例化哪一个类。
  • 使用场景:当需要让子类决定创建哪种对象时,如不同类型的产品创建。
1.3 抽象工厂模式(Abstract Factory)
  • 定义:提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。
  • 使用场景:当产品有多个维度或系列时,如跨平台 UI 组件。
1.4 建造者模式(Builder)
  • 定义:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
  • 使用场景:构建复杂对象时,尤其是涉及多个步骤的创建过程,如创建多步的表单。
1.5 原型模式(Prototype)
  • 定义:通过复制已有对象来创建新的对象,而不是通过实例化类。
  • 使用场景:当创建新对象的代价比较昂贵时,如对象初始化需要消耗较多资源。

2. 结构型模式(Structural Patterns)

结构型模式关注类或对象的组合,目的是帮助设计更灵活、松耦合的结构。

2.1 适配器模式(Adapter)
  • 定义:将一个类的接口转换为客户希望的另一个接口,解决接口不兼容的问题。
  • 使用场景:当现有类不能与其他代码兼容时,如新旧系统的对接。
2.2 桥接模式(Bridge)
  • 定义:将抽象部分与其实现部分分离,使它们可以独立变化。
  • 使用场景:需要在抽象和具体实现之间保持灵活性,如图形渲染系统中不同平台的渲染实现。
2.3 装饰器模式(Decorator)
  • 定义:动态地给对象添加新的功能,而不影响其他对象。
  • 使用场景:当不希望通过继承来增加类的功能时,如动态增加组件的功能。
2.4 组合模式(Composite)
  • 定义:将对象组合成树形结构以表示"部分-整体"的层次结构。
  • 使用场景:当需要处理对象层次结构时,如文件系统、UI 组件树。
2.5 外观模式(Facade)
  • 定义:为子系统中的一组接口提供一个一致的接口,简化客户端的使用。
  • 使用场景:为复杂的子系统提供一个简单的入口,如操作数据库的统一接口。
2.6 享元模式(Flyweight)
  • 定义:通过共享已经存在的对象来减少内存消耗。
  • 使用场景:当系统中存在大量相似对象时,如大量图形对象的共享。
2.7 代理模式(Proxy)
  • 定义:为其他对象提供一种代理以控制对该对象的访问。
  • 使用场景:需要在访问对象前后加入额外的操作时,如虚拟代理、远程代理。

3. 行为型模式(Behavioral Patterns)

行为型模式关注对象之间的通信,目的是提高系统中对象的交互方式。

3.1 模板方法模式(Template Method)
  • 定义:定义一个操作的骨架,而将一些步骤延迟到子类中。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
  • 使用场景:有固定步骤但部分步骤需要不同实现时,如业务处理流程。
3.2 策略模式(Strategy)
  • 定义:定义一系列算法,将每个算法封装起来,并使它们可以相互替换。
  • 使用场景:需要在运行时选择不同的算法时,如排序算法的选择。
3.3 观察者模式(Observer)
  • 定义:定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,其相关依赖对象都能收到通知并自动更新。
  • 使用场景:对象间存在依赖关系时,如事件系统、发布-订阅模式。
3.4 状态模式(State)
  • 定义:允许对象在其内部状态改变时改变其行为。
  • 使用场景:对象有多个状态,每个状态的行为不同时,如状态机、事务处理。
3.5 命令模式(Command)
  • 定义:将请求封装为对象,使得可以用不同的请求来参数化其他对象。
  • 使用场景:需要将操作请求封装为对象时,如命令队列、回滚操作。
3.6 职责链模式(Chain of Responsibility)
  • 定义:将多个处理器组织成一条链,沿着链传递请求,直到有对象处理它为止。
  • 使用场景:多个对象都有可能处理请求,但处理者未知时,如审批流程。
3.7 中介者模式(Mediator)
  • 定义:通过一个中介对象来封装一系列对象之间的交互。
  • 使用场景:多个对象之间的通信复杂时,如聊天室中消息的转发。
3.8 迭代器模式(Iterator)
  • 定义:提供一种方法顺序访问集合对象中的各个元素,而不暴露其内部表示。
  • 使用场景:需要遍历集合对象时,如链表、数组等集合类。
3.9 备忘录模式(Memento)
  • 定义:在不破坏封装的前提下,捕获对象的内部状态,并在之后进行恢复。
  • 使用场景:需要保存和恢复对象状态时,如撤销操作。
3.10 解释器模式(Interpreter)
  • 定义:为某个语言定义文法,并定义一个解释器来处理该语言中的句子。
  • 使用场景:当需要实现一种简单语言的解释器时,如正则表达式解析器。

4. 具体例子

4.1 单例模式
cpp 复制代码
#include <iostream>
#include <mutex>

class Singleton {
private:
    // 私有构造函数,确保外部无法直接实例化
    Singleton() {
        std::cout << "Singleton instance created.\n";
    }

    // 禁用拷贝构造和赋值运算符
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    // 静态指针,指向唯一的实例
    static Singleton* instance;
    static std::mutex mtx;

public:
    // 提供获取唯一实例的接口
    static Singleton* getInstance() {
        // 使用双重检查锁定以保证线程安全
        if (instance == nullptr) {
            std::lock_guard<std::mutex> lock(mtx);
            if (instance == nullptr) {
                instance = new Singleton();
            }
        }
        return instance;
    }

    void showMessage() {
        std::cout << "Hello from Singleton instance!\n";
    }
};

// 初始化静态成员
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

int main() {
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();
    
    s1->showMessage();
    
    // 输出两个指针是否相等,验证只有一个实例
    std::cout << (s1 == s2) << std::endl;  // 输出 1,表示是同一个实例
    return 0;
}
4.2 工厂方法模式
cpp 复制代码
#include <iostream>
#include <memory>

// 抽象产品类
class Product {
public:
    virtual void use() = 0;
    virtual ~Product() = default;
};

// 具体产品类1
class ConcreteProductA : public Product {
public:
    void use() override {
        std::cout << "Using Product A\n";
    }
};

// 具体产品类2
class ConcreteProductB : public Product {
public:
    void use() override {
        std::cout << "Using Product B\n";
    }
};

// 抽象工厂类
class Creator {
public:
    virtual std::unique_ptr<Product> createProduct() = 0;
    virtual ~Creator() = default;
};

// 具体工厂类1
class ConcreteCreatorA : public Creator {
public:
    std::unique_ptr<Product> createProduct() override {
        return std::make_unique<ConcreteProductA>();
    }
};

// 具体工厂类2
class ConcreteCreatorB : public Creator {
public:
    std::unique_ptr<Product> createProduct() override {
        return std::make_unique<ConcreteProductB>();
    }
};

int main() {
    // 使用工厂 A 创建产品
    std::unique_ptr<Creator> creatorA = std::make_unique<ConcreteCreatorA>();
    std::unique_ptr<Product> productA = creatorA->createProduct();
    productA->use();

    // 使用工厂 B 创建产品
    std::unique_ptr<Creator> creatorB = std::make_unique<ConcreteCreatorB>();
    std::unique_ptr<Product> productB = creatorB->createProduct();
    productB->use();

    return 0;
}
4.3 策略模式
cpp 复制代码
#include <iostream>
#include <memory>

// 抽象策略类
class Strategy {
public:
    virtual void execute() const = 0;
    virtual ~Strategy() = default;
};

// 具体策略类1
class ConcreteStrategyA : public Strategy {
public:
    void execute() const override {
        std::cout << "Executing Strategy A\n";
    }
};

// 具体策略类2
class ConcreteStrategyB : public Strategy {
public:
    void execute() const override {
        std::cout << "Executing Strategy B\n";
    }
};

// 上下文类
class Context {
private:
    std::unique_ptr<Strategy> strategy;

public:
    // 设置策略
    void setStrategy(std::unique_ptr<Strategy> s) {
        strategy = std::move(s);
    }

    // 执行策略
    void executeStrategy() const {
        if (strategy) {
            strategy->execute();
        }
    }
};

int main() {
    Context context;

    // 选择并执行策略 A
    context.setStrategy(std::make_unique<ConcreteStrategyA>());
    context.executeStrategy();

    // 切换到策略 B
    context.setStrategy(std::make_unique<ConcreteStrategyB>());
    context.executeStrategy();

    return 0;
}
4.4 观察者模式
cpp 复制代码
#include <iostream>
#include <vector>
#include <memory>

// 观察者接口
class Observer {
public:
    virtual void update(int newState) = 0;
    virtual ~Observer() = default;
};

// 被观察者(主题)类
class Subject {
private:
    std::vector<std::shared_ptr<Observer>> observers;
    int state;

public:
    void attach(const std::shared_ptr<Observer>& observer) {
        observers.push_back(observer);
    }

    void setState(int newState) {
        state = newState;
        notify();
    }

    void notify() {
        for (const auto& observer : observers) {
            observer->update(state);
        }
    }
};

// 具体观察者类
class ConcreteObserver : public Observer {
private:
    std::string name;

public:
    explicit ConcreteObserver(std::string n) : name(std::move(n)) {}

    void update(int newState) override {
        std::cout << "Observer " << name << " notified with state: " << newState << "\n";
    }
};

int main() {
    Subject subject;

    auto observer1 = std::make_shared<ConcreteObserver>("Observer1");
    auto observer2 = std::make_shared<ConcreteObserver>("Observer2");

    subject.attach(observer1);
    subject.attach(observer2);

    subject.setState(10);  // 通知所有观察者

    return 0;
}
相关推荐
无敌岩雀4 分钟前
C++设计模式创建型模式———单例模式
c++·单例模式·设计模式
canyuemanyue4 分钟前
C++单例模式
开发语言·c++·单例模式
冬天的枫树10 分钟前
人工智能原理实验一:知识的表示与推理实验
c++·人工智能
秋恬意20 分钟前
Java 反射机制详解
java·开发语言
黑不溜秋的22 分钟前
C++ 模板专题 - 标签分派(Tag Dispatching)
开发语言·c++·算法
skywind32 分钟前
为什么 C 语言数组是从 0 开始计数的?
c语言·开发语言·网络·c++
ღ᭄ꦿ࿐Never say never꧂36 分钟前
重生之我在Java世界------学工厂设计模式
java·设计模式·简单工厂模式·应用场景
ProcedureStone38 分钟前
【算法】排序算法总结
c++·算法·排序算法
尘浮生1 小时前
Java项目实战II基于Spring Boot的火锅店管理系统设计与实现(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·微信小程序·旅游
wrx繁星点点1 小时前
桥接模式:解耦抽象与实现的利器
android·java·开发语言·jvm·spring cloud·intellij-idea·桥接模式