设计模式讲座:C++中的单例、工厂和观察者
各位代码战士们,今天我们要来聊聊C++中的设计模式。设计模式就像是编程界的“武林秘籍”,它们是前辈们在无数次实战中总结出来的经验,可以帮助我们写出更优雅、更高效的代码。今天我们就聚焦于三个经典的设计模式:单例(Singleton)、工厂(Factory)和观察者(Observer)。准备好了吗?让我们开始吧!
第一章:单例模式——孤独的王者
什么是单例模式?
单例模式的核心思想就是:一个类只能有一个实例,并提供一个全局访问点。就像一个王国里只能有一个国王,而这个国王需要被所有人认识。
单例模式的应用场景
- 系统中需要一个共享资源,比如数据库连接池。
- 需要控制某个类的实例化过程。
C++实现单例模式
class Singleton {
private:
static Singleton* instance; // 指向唯一实例的指针
Singleton() {} // 私有构造函数,防止外部实例化
public:
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton(); // 懒汉式初始化
}
return instance;
}
void showMessage() {
std::cout << "Hello from Singleton!" << std::endl;
}
};
// 初始化静态成员变量
Singleton* Singleton::instance = nullptr;
int main() {
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
if (s1 == s2) {
std::cout << "s1 and s2 are the same instance." << std::endl;
}
s1->showMessage();
return 0;
}
注意事项
- 线程安全问题:如果多个线程同时调用
getInstance()
,可能会创建多个实例。可以通过加锁解决。 - 内存泄漏:手动管理内存时,记得释放单例对象。
第二章:工厂模式——创造万物的魔术师
什么是工厂模式?
工厂模式的核心思想是:将对象的创建过程封装起来,让客户端无需知道具体的创建细节。它就像一个神奇的工厂,输入原料,输出产品。
工厂模式的类型
- 简单工厂模式:负责创建一系列相关或依赖的对象。
- 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
- 抽象工厂模式:提供一个创建一系列相关或依赖对象的接口,而无需指定它们的具体类。
C++实现简单工厂模式
class Product {
public:
virtual void use() = 0; // 纯虚函数,定义产品的行为
virtual ~Product() {} // 虚析构函数
};
class ConcreteProductA : public Product {
public:
void use() override {
std::cout << "Using ConcreteProductA" << std::endl;
}
};
class ConcreteProductB : public Product {
public:
void use() override {
std::cout << "Using ConcreteProductB" << std::endl;
}
};
class Factory {
public:
static Product* createProduct(char type) {
if (type == 'A') {
return new ConcreteProductA();
} else if (type == 'B') {
return new ConcreteProductB();
} else {
return nullptr;
}
}
};
int main() {
Product* productA = Factory::createProduct('A');
productA->use();
Product* productB = Factory::createProduct('B');
productB->use();
delete productA;
delete productB;
return 0;
}
工厂模式的优势
- 解耦:客户端不需要知道具体的产品类。
- 扩展性:新增产品时只需修改工厂逻辑,无需改动客户端代码。
第三章:观察者模式——信息的传播者
什么是观察者模式?
观察者模式的核心思想是:定义对象间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会收到通知并自动更新。它就像新闻发布会,记者们(观察者)会实时报道总统(被观察者)的言行。
观察者模式的应用场景
- GUI事件处理系统。
- 订阅-发布系统。
C++实现观察者模式
#include <vector>
#include <iostream>
class Observer {
public:
virtual void update() = 0;
virtual ~Observer() {}
};
class Subject {
private:
std::vector<Observer*> observers;
public:
void attach(Observer* observer) {
observers.push_back(observer);
}
void detach(Observer* observer) {
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify() {
for (auto obs : observers) {
obs->update();
}
}
};
class ConcreteObserver : public Observer {
private:
std::string name;
public:
ConcreteObserver(const std::string& n) : name(n) {}
void update() override {
std::cout << name << " received notification." << std::endl;
}
};
class ConcreteSubject : public Subject {
public:
void doSomething() {
std::cout << "ConcreteSubject: Doing something important..." << std::endl;
notify(); // 通知所有观察者
}
};
int main() {
ConcreteSubject subject;
ConcreteObserver observer1("Observer1");
ConcreteObserver observer2("Observer2");
subject.attach(&observer1);
subject.attach(&observer2);
subject.doSomething();
subject.detach(&observer1);
subject.doSomething();
return 0;
}
观察者模式的优势
- 松耦合:观察者和被观察者之间没有直接依赖。
- 动态绑定:可以随时添加或移除观察者。
总结
今天我们聊了三个经典的设计模式:单例、工厂和观察者。它们各自有不同的应用场景和实现方式,但都旨在解决软件开发中的常见问题。
模式名称 | 核心思想 | 优点 |
---|---|---|
单例模式 | 保证一个类只有一个实例,并提供一个全局访问点 | 控制资源、简化全局状态管理 |
工厂模式 | 将对象的创建过程封装起来,让客户端无需知道具体的创建细节 | 解耦、扩展性强 |
观察者模式 | 定义对象间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会更新 | 松耦合、支持动态绑定 |
希望今天的分享能让你对设计模式有更深的理解。记住,设计模式不是万能药,而是工具箱里的工具。选择合适的工具才能事半功倍!