1. 基于C++纯虚函数实现观察者模式
- 定义Subject类
#include <vector>
#include <memory>
class Observer;
class Subject {
public:
virtual ~Subject() = default;
// 纯虚函数,用于注册观察者
virtual void attach(std::shared_ptr<Observer> observer) = 0;
// 纯虚函数,用于移除观察者
virtual void detach(std::shared_ptr<Observer> observer) = 0;
// 纯虚函数,用于通知所有观察者
virtual void notify() = 0;
};
- 定义Observer类
class Subject;
class Observer {
public:
virtual ~Observer() = default;
// 纯虚函数,用于接收通知
virtual void update(const Subject& subject) = 0;
};
- 具体Subject类实现
class ConcreteSubject : public Subject {
private:
std::vector<std::shared_ptr<Observer>> observers;
public:
void attach(std::shared_ptr<Observer> observer) override {
observers.push_back(observer);
}
void detach(std::shared_ptr<Observer> observer) override {
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify() override {
for (const auto& observer : observers) {
observer->update(*this);
}
}
};
- 具体Observer类实现
class ConcreteObserver : public Observer {
public:
void update(const Subject& subject) override {
// 处理更新逻辑
}
};
2. 处理动态添加和删除观察者
- 添加观察者:在
Subject
类中定义attach
纯虚函数,具体Subject
类实现此函数,将观察者添加到观察者列表。例如上述ConcreteSubject
的attach
函数。
- 删除观察者:在
Subject
类中定义detach
纯虚函数,具体Subject
类实现此函数,从观察者列表中移除指定观察者。如ConcreteSubject
的detach
函数。
3. 优化通知过程以避免性能瓶颈
- 批量通知:可以在
Subject
状态改变时,先记录改变,然后在合适时机(如事务结束)统一通知,减少频繁通知开销。
- 减少不必要通知:
Subject
内部记录状态变化标识,只有当状态真正变化时才通知观察者,避免无效通知。
- 异步通知:使用多线程或异步队列,将通知任务放入队列,由专门线程处理,避免阻塞主线程。
4. 多线程环境下保证线程安全
- 互斥锁:在
Subject
类中使用std::mutex
保护观察者列表的修改和通知过程。例如在attach
、detach
和notify
函数中加锁。
class ConcreteSubject : public Subject {
private:
std::vector<std::shared_ptr<Observer>> observers;
std::mutex observerMutex;
public:
void attach(std::shared_ptr<Observer> observer) override {
std::lock_guard<std::mutex> lock(observerMutex);
observers.push_back(observer);
}
void detach(std::shared_ptr<Observer> observer) override {
std::lock_guard<std::mutex> lock(observerMutex);
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify() override {
std::lock_guard<std::mutex> lock(observerMutex);
for (const auto& observer : observers) {
observer->update(*this);
}
}
};
- 读写锁:如果读操作(如
notify
)频繁,写操作(如attach
和detach
)较少,可以使用读写锁,读操作共享锁,写操作独占锁,提高并发性能。
5. 纯虚函数在这种复杂设计模式中的优势
- 抽象接口定义:明确规定了
Subject
和Observer
必须实现的接口,保证了不同实现类之间的一致性和规范性。
- 多态性支持:使不同的
Subject
和Observer
实现类能够通过统一接口交互,便于系统扩展和维护。
- 解耦依赖:
Subject
和Observer
之间仅通过抽象接口依赖,降低了模块间耦合度。
6. 纯虚函数在这种复杂设计模式中的潜在问题
- 增加实现复杂度:每个具体类都必须实现纯虚函数,对于复杂逻辑可能导致实现代码量增加。
- 运行时错误风险:如果某个具体类没有正确实现纯虚函数,运行时会出现未定义行为,排查错误相对困难。
- 内存管理问题:在使用智能指针管理
Subject
和Observer
对象时,如果纯虚函数的实现涉及到内存操作,可能会引发内存泄漏或悬空指针问题。