C++四大设计模式:单例、工厂、观察者、策略

引言

在前面的文章中,我们学习了 C++ 语法、STL、数据结构。这些都是"怎么写代码"的工具。而设计模式解决的是更高层次的问题------"代码怎么组织才更好"。

设计模式是前辈们总结的、经过反复验证的代码组织方案。它不是凭空发明的,而是在无数项目中"踩坑"后提炼出的最佳实践。掌握设计模式,能让你写出更易维护、更易扩展、更易复用的代码。

本文聚焦 C++ 中最常用的四种设计模式:单例模式工厂模式观察者模式策略模式

第一部分:单例模式

一、什么是单例模式

保证一个类只有一个实例,并提供全局访问点。比如程序的配置管理器、日志系统、数据库连接池------这些东西整个程序只需要一份。

二、懒汉式(用到才创建)

cpp 复制代码
#include <iostream>
#include <mutex>
using namespace std;

class Singleton {
private:
    static Singleton* instance;
    static mutex mtx;

    // 构造函数私有!外部不能 new
    Singleton() { cout << "单例创建" << endl; }
    
    // 禁止拷贝和赋值
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

public:
    // 全局访问点(线程安全)
    static Singleton* getInstance() {
        if (instance == nullptr) {
            lock_guard<mutex> lock(mtx);   // 加锁
            if (instance == nullptr) {      // 双重检查
                instance = new Singleton();
            }
        }
        return instance;
    }

    void doSomething() { cout << "工作" << endl; }
};

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

int main() {
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();
    
    cout << (s1 == s2) << endl;  // 1(同一个对象)
    // Singleton s3;  // 错误!构造私有
}

为什么用双重检查锁?

三、C++11 最简写法(推荐)

C++11 保证了静态局部变量的线程安全,一行搞定:

cpp 复制代码
class Singleton {
private:
    Singleton() = default;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

public:
    static Singleton& getInstance() {
        static Singleton instance;  // C++11 保证线程安全!
        return instance;
    }
};

第二部分:工厂模式

一、简单工厂

把对象的创建逻辑集中到一个工厂类中,调用者不需要知道具体怎么创建。

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

// 产品基类
class Animal {
public:
    virtual void speak() = 0;
    virtual ~Animal() = default;
};

// 具体产品
class Dog : public Animal {
public:
    void speak() override { cout << "汪汪" << endl; }
};

class Cat : public Animal {
public:
    void speak() override { cout << "喵喵" << endl; }
};

// 简单工厂
class AnimalFactory {
public:
    static Animal* createAnimal(const string& type) {
        if (type == "dog") return new Dog();
        if (type == "cat") return new Cat();
        return nullptr;
    }
};

int main() {
    Animal* dog = AnimalFactory::createAnimal("dog");
    dog->speak();  // 汪汪
    
    Animal* cat = AnimalFactory::createAnimal("cat");
    cat->speak();  // 喵喵
    
    delete dog;
    delete cat;
}

二、工厂方法模式

每个具体产品对应一个具体工厂,新增产品时不修改已有代码(开闭原则)。

cpp 复制代码
// 抽象工厂
class AnimalFactory {
public:
    virtual Animal* createAnimal() = 0;
    virtual ~AnimalFactory() = default;
};

// 具体工厂
class DogFactory : public AnimalFactory {
public:
    Animal* createAnimal() override { return new Dog(); }
};

class CatFactory : public AnimalFactory {
public:
    Animal* createAnimal() override { return new Cat(); }
};

int main() {
    DogFactory dogFactory;
    Animal* dog = dogFactory.createAnimal();
    dog->speak();  // 汪汪
    
    CatFactory catFactory;
    Animal* cat = catFactory.createAnimal();
    cat->speak();  // 喵喵
    
    delete dog;
    delete cat;
}
工厂类型 特点 适用场景
简单工厂 一个工厂创建所有产品 产品类型少,变化不频繁
工厂方法 每个产品对应一个工厂 产品类型多,经常新增

第三部分:观察者模式

定义一对多依赖关系,当被观察者状态变化时,自动通知所有观察者。比如 GUI 的事件监听、消息订阅通知。

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

// 观察者接口
class Observer {
public:
    virtual void update(const string& message) = 0;
    virtual ~Observer() = default;
};

// 被观察者
class Subject {
private:
    vector<Observer*> observers;
    string state;
public:
    // 注册观察者
    void attach(Observer* obs) {
        observers.push_back(obs);
    }
    
    // 移除观察者
    void detach(Observer* obs) {
        observers.erase(
            remove(observers.begin(), observers.end(), obs),
            observers.end()
        );
    }
    
    // 通知所有观察者
    void notify() {
        for (auto* obs : observers) {
            obs->update(state);
        }
    }
    
    // 改变状态并通知
    void setState(const string& newState) {
        state = newState;
        notify();  // 状态一改变就通知
    }
};

// 具体观察者
class User : public Observer {
private:
    string name;
public:
    User(const string& name) : name(name) {}
    
    void update(const string& message) override {
        cout << name << " 收到通知:" << message << endl;
    }
};

int main() {
    Subject subject;
    
    User alice("Alice");
    User bob("Bob");
    
    subject.attach(&alice);
    subject.attach(&bob);
    
    subject.setState("新版本发布了!");
    // Alice 收到通知:新版本发布了!
    // Bob 收到通知:新版本发布了!
    
    subject.detach(&bob);
    subject.setState("服务器维护中...");
    // Alice 收到通知:服务器维护中...
    // (Bob 已取消订阅,不会收到)
}

第四部分:策略模式

定义一系列算法,把它们封装起来,让它们可以互相替换。比如排序可以选快排、归并;支付可以选微信、支付宝。

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 策略接口
class SortStrategy {
public:
    virtual void sort(vector<int>& data) = 0;
    virtual ~SortStrategy() = default;
};

// 具体策略:升序
class AscendingSort : public SortStrategy {
public:
    void sort(vector<int>& data) override {
        std::sort(data.begin(), data.end());
    }
};

// 具体策略:降序
class DescendingSort : public SortStrategy {
public:
    void sort(vector<int>& data) override {
        std::sort(data.begin(), data.end(), greater<int>());
    }
};

// 使用策略的类
class DataProcessor {
private:
    SortStrategy* strategy;
public:
    void setStrategy(SortStrategy* s) { strategy = s; }
    
    void process(vector<int>& data) {
        if (strategy) {
            strategy->sort(data);
        }
    }
};

int main() {
    vector<int> data = {5, 2, 8, 1, 9};
    DataProcessor processor;
    
    AscendingSort asc;
    DescendingSort desc;
    
    // 用升序策略
    processor.setStrategy(&asc);
    processor.process(data);  // 1 2 5 8 9
    
    // 切换到降序策略
    processor.setStrategy(&desc);
    processor.process(data);  // 9 8 5 2 1
}

策略模式的核心 :用组合 代替继承,算法可以在运行时灵活切换,不需要改代码。


总结

一、四种模式速查

模式 核心思想 关键实现
单例 全局唯一实例 构造私有 + 静态 getInstance()
工厂 把创建逻辑封装起来 工厂类返回产品指针
观察者 状态变化自动通知 vector<Observer*> + notify()
策略 算法可替换 策略接口 + setStrategy()

二、一句话记忆

单例构造私有化保证全局唯一,工厂把创建和使用分离,观察者实现一对多自动通知,策略让算法可以随时替换------四大模式都是为了让代码更灵活、更好改、更好测。

相关推荐
码智社8 分钟前
JSON 零基础到资深全体系教程
java·json
小星星闪亮登场1 小时前
2026萌新联赛第三场-- (郑州轻工业大学)
数据结构·c++·经验分享·算法·贪心算法·排序算法·深度优先
wgego1 小时前
基础的反序列化一些总结(php和java)
java·开发语言·笔记
梓䈑1 小时前
【用 Vibe Coding 实现的 C++17 在线判题系统】前端开发 + Web 自动化测试
前端·c++·ai编程
冻柠檬飞冰走茶1 小时前
PTA基础编程题目集 7-8超速判断(C++语言实现)
开发语言·数据结构·c++·算法
机建狂魔2 小时前
Codex 接入第三方模型 API 实战:以 Mimo 为例
java·服务器·数据库·ai·ai编程·codex
TunerT_TQ2 小时前
Valhalla 静态工程审阅 #018|MMCV 源码证据驱动评测【大厂开源基础设施特辑】
c++·开源·mfc·#计算机视觉·#商汤科技·#openmmlab·#静态源码审计
山峰哥2 小时前
数据库工程与SQL调优:从慢查询到秒级响应的实战之路
java·开发语言·数据库·sql·深度优先·启发式算法
乐观的Terry2 小时前
11、发布系统-用户认证与权限体系
java·spring boot·spring·spring cloud·mybatis
前端开发张小七2 小时前
Java 学习笔记 · 第二课:面向对象核心(封装、继承、多态)及接口与异常
java·后端·程序员