C++四大设计模式:单例、工厂、观察者、策略
引言在前面的文章中我们学习了 C 语法、STL、数据结构。这些都是怎么写代码的工具。而设计模式解决的是更高层次的问题——代码怎么组织才更好。设计模式是前辈们总结的、经过反复验证的代码组织方案。它不是凭空发明的而是在无数项目中踩坑后提炼出的最佳实践。掌握设计模式能让你写出更易维护、更易扩展、更易复用的代码。本文聚焦 C 中最常用的四种设计模式单例模式、工厂模式、观察者模式和策略模式。第一部分单例模式一、什么是单例模式保证一个类只有一个实例并提供全局访问点。比如程序的配置管理器、日志系统、数据库连接池——这些东西整个程序只需要一份。二、懒汉式用到才创建#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_guardmutex 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; // 错误构造私有 }为什么用双重检查锁三、C11 最简写法推荐C11 保证了静态局部变量的线程安全一行搞定class Singleton { private: Singleton() default; Singleton(const Singleton) delete; Singleton operator(const Singleton) delete; public: static Singleton getInstance() { static Singleton instance; // C11 保证线程安全 return instance; } };第二部分工厂模式一、简单工厂把对象的创建逻辑集中到一个工厂类中调用者不需要知道具体怎么创建。#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; }二、工厂方法模式每个具体产品对应一个具体工厂新增产品时不修改已有代码开闭原则。// 抽象工厂 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 的事件监听、消息订阅通知。#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: vectorObserver* 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 已取消订阅不会收到 }第四部分策略模式定义一系列算法把它们封装起来让它们可以互相替换。比如排序可以选快排、归并支付可以选微信、支付宝。#include iostream #include vector #include algorithm using namespace std; // 策略接口 class SortStrategy { public: virtual void sort(vectorint data) 0; virtual ~SortStrategy() default; }; // 具体策略升序 class AscendingSort : public SortStrategy { public: void sort(vectorint data) override { std::sort(data.begin(), data.end()); } }; // 具体策略降序 class DescendingSort : public SortStrategy { public: void sort(vectorint data) override { std::sort(data.begin(), data.end(), greaterint()); } }; // 使用策略的类 class DataProcessor { private: SortStrategy* strategy; public: void setStrategy(SortStrategy* s) { strategy s; } void process(vectorint data) { if (strategy) { strategy-sort(data); } } }; int main() { vectorint 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()工厂把创建逻辑封装起来工厂类返回产品指针观察者状态变化自动通知vectorObserver*notify()策略算法可替换策略接口 setStrategy()二、一句话记忆单例构造私有化保证全局唯一工厂把创建和使用分离观察者实现一对多自动通知策略让算法可以随时替换——四大模式都是为了让代码更灵活、更好改、更好测。