单例模式
- 适用场景:在整个应用程序中,某个类的实例只需要存在一个,例如数据库连接池、日志记录器等场景。
- 原理:保证一个类仅有一个实例,并提供一个全局访问点。通过将构造函数设为私有,防止外部直接创建实例,使用静态成员函数来控制实例的创建和访问。
- 代码实现体现可维护性:例如在数据库连接池单例中,后续若要修改连接池的初始化逻辑,只需在单例类的内部修改,不会影响到其他使用连接池的地方。因为所有对连接池的访问都通过单例类的全局访问点,一处修改,到处生效。
class Singleton {
private:
static Singleton* instance;
Singleton() {}
~Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public:
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
};
策略模式
- 适用场景:当有多种算法或行为可以选择,且在运行时需要动态切换时,例如不同的排序算法、不同的支付方式等。
- 原理:定义一系列算法,将每个算法封装起来,使它们可以相互替换。通过将算法封装成独立的类,让这些类实现相同的接口,客户端可以根据需要选择不同的策略类。
- 代码实现体现可维护性:以不同排序算法为例,如果新增一种排序算法,只需创建一个新的策略类实现相应接口,而无需修改原有排序算法的代码和使用排序功能的客户端代码。客户端只关心接口,不关心具体实现。
class SortStrategy {
public:
virtual void sort(int* arr, int n) = 0;
};
class BubbleSort : public SortStrategy {
public:
void sort(int* arr, int n) override {
// 冒泡排序实现
}
};
class QuickSort : public SortStrategy {
public:
void sort(int* arr, int n) override {
// 快速排序实现
}
};
class Sorter {
private:
SortStrategy* strategy;
public:
Sorter(SortStrategy* s) : strategy(s) {}
void sortArray(int* arr, int n) {
strategy->sort(arr, n);
}
};
观察者模式
- 适用场景:当一个对象的状态发生变化时,需要自动通知其他多个对象,例如图形界面中的事件监听、消息推送系统等。
- 原理:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。被观察对象(主题)维护一个观察者列表,当状态改变时,遍历列表通知所有观察者。
- 代码实现体现可维护性:例如在消息推送系统中,如果新增一种类型的消息接收者(观察者),只需创建新的观察者类实现相应接口并注册到主题中,不会影响主题和其他观察者的代码。主题只负责通知,不关心具体观察者的行为。
#include <vector>
#include <iostream>
class Observer {
public:
virtual void update() = 0;
};
class Subject {
private:
std::vector<Observer*> observers;
public:
void attach(Observer* o) {
observers.push_back(o);
}
void detach(Observer* o) {
for (auto it = observers.begin(); it != observers.end(); ++it) {
if (*it == o) {
observers.erase(it);
break;
}
}
}
void notify() {
for (Observer* o : observers) {
o->update();
}
}
};
class ConcreteObserver : public Observer {
private:
Subject* subject;
public:
ConcreteObserver(Subject* s) : subject(s) {
subject->attach(this);
}
~ConcreteObserver() {
subject->detach(this);
}
void update() override {
std::cout << "ConcreteObserver updated" << std::endl;
}
};