马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
观察者模式 (Observer)
观察者模式 是一种举动型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,其依赖者(观察者)会收到关照并主动更新。
意图
- 定义对象之间的一对多依赖关系。
- 当一个对象状态发生厘革时,关照所有依赖于它的对象。
利用场景
- 变乱驱动系统:
- 如 GUI 程序中的按钮点击变乱,按钮关照所有监听器。
- 数据厘革关照:
- 解耦对象之间的依赖:
参与者角色
- 主题 (Subject)
- 被观察者,维护观察者列表,并在状态发生厘革时关照所有观察者。
- 观察者 (Observer)
- 具体主题 (ConcreteSubject)
- 实现具体的主题逻辑,存储状态,并在状态改变时关照观察者。
- 具体观察者 (ConcreteObserver)
示例代码
以下代码展示了观察者模式的实现,利用 C++ 的现代特性(如 std::function、std::vector、shared_ptr)。
- #include <iostream>
- #include <vector>
- #include <memory>
- #include <functional>
- #include <string>
- // 观察者接口
- class Observer {
- public:
- virtual ~Observer() = default;
- virtual void update(const std::string& message) = 0; // 接收通知
- };
- // 具体观察者:实现观察者接口
- class ConcreteObserver : public Observer {
- private:
- std::string name; // 观察者名称,用于标识
- public:
- explicit ConcreteObserver(const std::string& observerName) : name(observerName) {}
- void update(const std::string& message) override {
- std::cout << "观察者 [" << name << "] 收到通知: " << message << std::endl;
- }
- };
- // 被观察者接口
- 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; // 通知观察者
- };
- // 具体被观察者:实现被观察者接口
- class ConcreteSubject : public Subject {
- private:
- std::vector<std::shared_ptr<Observer>> observers; // 存储观察者的列表
- std::string state; // 被观察者的状态
- 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 setState(const std::string& newState) {
- state = newState;
- notify(); // 状态改变时通知所有观察者
- }
- void notify() override {
- for (const auto& observer : observers) {
- observer->update(state);
- }
- }
- };
- // 客户端代码
- int main() {
- auto subject = std::make_shared<ConcreteSubject>();
- // 创建多个观察者
- auto observer1 = std::make_shared<ConcreteObserver>("Observer1");
- auto observer2 = std::make_shared<ConcreteObserver>("Observer2");
- auto observer3 = std::make_shared<ConcreteObserver>("Observer3");
- // 观察者订阅被观察者
- subject->attach(observer1);
- subject->attach(observer2);
- subject->attach(observer3);
- // 修改被观察者的状态,通知观察者
- std::cout << "修改状态为: 状态A" << std::endl;
- subject->setState("状态A");
- // 移除一个观察者
- subject->detach(observer2);
- std::cout << "修改状态为: 状态B" << std::endl;
- subject->setState("状态B");
- return 0;
- }
复制代码 代码剖析
1. 观察者接口 (Observer)
- class Observer {
- public:
- virtual ~Observer() = default;
- virtual void update(const std::string& message) = 0; // 接收通知
- };
复制代码 2. 具体观察者 (ConcreteObserver)
- 实现了 Observer 接口,并通过 update 方法更新状态:
- class ConcreteObserver : public Observer {
- private:
- std::string name;
- public:
- explicit ConcreteObserver(const std::string& observerName) : name(observerName) {}
- void update(const std::string& message) override {
- std::cout << "观察者 [" << name << "] 收到通知: " << message << std::endl;
- }
- };
复制代码 3. 被观察者接口 (Subject)
- 定义了添加、移除观察者的方法,以及关照观察者的 notify 方法:
- 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;
- };
复制代码 4. 具体被观察者 (ConcreteSubject)
- class ConcreteSubject : public Subject {
- private:
- std::vector<std::shared_ptr<Observer>> observers;
- std::string state;
- public:
- void setState(const std::string& newState) {
- state = newState;
- notify(); // 状态改变时通知所有观察者
- }
- void notify() override {
- for (const auto& observer : observers) {
- observer->update(state);
- }
- }
- };
复制代码 5. 客户端
- 客户端通过 attach 方法订阅观察者,并通过 setState 方法触发关照:
- auto subject = std::make_shared<ConcreteSubject>();
- auto observer1 = std::make_shared<ConcreteObserver>("Observer1");
- subject->attach(observer1);
- subject->setState("状态A");
复制代码 优缺点
优点
缺点
适用场景
总结
观察者模式通过定义一对多的依赖关系,解决了对象之间的动态联动问题,是变乱驱动系统中非常重要的设计模式。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |