马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
观察者模式的动机意图
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象之间的一种一对多的依赖关系,使得当一个对象的状态发生改变时,全部依赖于它的对象都能够主动收到通知并进行相应的更新。
动机意图:
- 解耦:观察者模式的动机在于解耦对象之间的关系。具体来说,它让一个对象(被观察者或主题)不必要知道具体有哪些对象(观察者)依赖于它,从而降低了对象之间的耦合度。
- 主动通知:当被观察者的状态发生变化时,全部观察者都会主动收到通知,并执行相应的操纵。这种机制使得体系更加灵活,易于扩展和维护。
适用场合
观察者模式适用于以下场景:
- 当一个对象的状态变化必要通知其他对象,而且你不知道这些对象的具体数量和类型时。例如,图形用户界面(GUI)中的按钮点击事件,可以通知多个监听器。
- 当必要在不修改被观察者代码的情况下,动态添加或删除观察者时。这种情况下,观察者模式可以实现松耦合的设计。
- 当一个对象的状态变化会影响多个其他对象,而且这些对象必要根据状态变化主动更新时。例如,股票价格的变化会影响多个投资者的计谋。
观察者模式的变体
观察者模式有几种常见的变体,具体取决于通知机制、更新方式以及观察者的管理方式。以下是几种常见的变体:
- 推模型(Push Model):
- 特点:被观察者主动将状态变化的信息推送给全部观察者。
- 优点:观察者不必要知道被观察者的内部结构,只必要处理推送过来的数据。
- 缺点:被观察者必要知道观察者的接口,可能会导致观察者和被观察者之间的耦合。
- 拉模型(Pull Model):
- 特点:被观察者仅通知观察者状态已发生变化,观察者必要主动去拉取被观察者的具体状态。
- 优点:观察者可以只拉取自己感兴趣的部分状态,淘汰不必要的数据传输。
- 缺点:观察者必要了解被观察者的内部结构。
- 事件机制(Event-based Model):
- 特点:被观察者通过事件通知观察者,观察者可以订阅特定类型的事件。
- 优点:可以处理更复杂的事件类型,支持多种事件的订阅和处理。
- 缺点:实现复杂度较高。
- 观察者队列(Observer Queue):
- 特点:使用队列来管理观察者,当被观察者状态变化时,将通知放入队列中,观察者从队列中取出通知进行处理。
- 优点:可以实现异步通知,进步体系的并发性能。
- 缺点:可能引入额外的复杂性和延迟。
- 弱引用观察者(Weak Reference Observer):
- 特点:使用弱引用(Weak Reference)来管理观察者,防止观察者对象未被开释时导致的内存泄漏。
- 优点:可以避免内存泄漏题目。
- 缺点:必要额外的机制来管理弱引用。
总结
观察者模式通过解耦对象之间的关系,提供了一种灵活且易于扩展的通知机制。它的变体如推模型、拉模型、事件机制等,使得它在差别的场景中可以有差别的实现方式。基于观察者模式的特点,发布-订阅模式、事件驱动架构、MVC模式等软件架构模式在现代软件开发中得到了广泛的应用。这些架构模式不但进步了体系的灵活性和可维护性,还使得体系在面对变化时能够更加从容应对。
下面是观察者模式的差别变体的C++代码示例,包罗推模型、拉模型、事件机制、观察者队列和弱引用观察者。
1. 推模型(Push Model)
在推模型中,被观察者将状态变化的信息主动推送给全部观察者。
示例代码
- #include <iostream>
- #include <vector>
- #include <string>
- // 观察者接口
- class Observer {
- public:
- virtual void update(const std::string& message) = 0;
- virtual ~Observer() = default;
- };
- // 具体观察者
- class ConcreteObserver : public Observer {
- public:
- void update(const std::string& message) override {
- std::cout << "Observer received message: " << message << std::endl;
- }
- };
- // 被观察者接口
- class Subject {
- public:
- virtual void attach(Observer* observer) = 0;
- virtual void detach(Observer* observer) = 0;
- virtual void notify(const std::string& message) = 0;
- virtual ~Subject() = default;
- };
- // 具体被观察者
- class ConcreteSubject : public Subject {
- private:
- std::vector<Observer*> observers;
- public:
- void attach(Observer* observer) override {
- observers.push_back(observer);
- }
- void detach(Observer* observer) override {
- observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
- }
- void notify(const std::string& message) override {
- for (Observer* observer : observers) {
- observer->update(message);
- }
- }
- void changeState(const std::string& message) {
- std::cout << "Subject state changed. Notifying observers..." << std::endl;
- notify(message);
- }
- };
- int main() {
- ConcreteSubject subject;
- ConcreteObserver observer1;
- ConcreteObserver observer2;
- subject.attach(&observer1);
- subject.attach(&observer2);
- subject.changeState("Hello Observers!");
- subject.detach(&observer1);
- subject.changeState("Hello again!");
- return 0;
- }
复制代码
2. 拉模型(Pull Model)
在拉模型中,被观察者仅通知观察者状态已发生变化,观察者必要主动去拉取被观察者的具体状态。
示例代码
- #include <iostream>
- #include <vector>
- #include <string>
- // 被观察者接口
- class Subject {
- public:
- virtual std::string getState() const = 0;
- virtual void notify() = 0;
- virtual void setState(const std::string& state) = 0;
- virtual void attach(class Observer* observer) = 0;
- virtual void detach(class Observer* observer) = 0;
- virtual ~Subject() = default;
- };
- // 具体被观察者
- class ConcreteSubject : public Subject {
- private:
- std::string state;
- std::vector<class Observer*> observers;
- public:
- std::string getState() const override {
- return state;
- }
- void setState(const std::string& state) override {
- this->state = state;
- notify();
- }
- void attach(Observer* observer) override {
- observers.push_back(observer);
- }
- void detach(Observer* observer) override {
- observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
- }
- void notify() override {
- for (Observer* observer : observers) {
- observer->update();
- }
- }
- };
- // 观察者接口
- class Observer {
- protected:
- Subject* subject;
- public:
- Observer(Subject* subject) : subject(subject) {}
- virtual void update() = 0;
- virtual ~Observer() = default;
- };
- // 具体观察者
- class ConcreteObserver : public Observer {
- public:
- ConcreteObserver(Subject* subject) : Observer(subject) {}
- void update() override {
- std::string state = subject->getState();
- std::cout << "Observer received state: " << state << std::endl;
- }
- };
- int main() {
- ConcreteSubject subject;
- ConcreteObserver observer1(&subject);
- ConcreteObserver observer2(&subject);
- subject.attach(&observer1);
- subject.attach(&observer2);
- subject.setState("State 1");
- subject.detach(&observer1);
- subject.setState("State 2");
- return 0;
- }
复制代码
3. 事件机制(Event-based Model)
在事件机制中,被观察者通过事件通知观察者,观察者可以订阅特定类型的事件。
示例代码
- #include <iostream>
- #include <vector>
- #include <string>
- #include <map>
- #include <functional>
- // 事件类型
- enum class EventType {
- StateChanged,
- DataUpdated
- };
- // 事件
- class Event {
- public:
- EventType type;
- std::string data;
- Event(EventType type, const std::string& data) : type(type), data(data) {}
- };
- // 观察者接口
- class Observer {
- public:
- virtual void handleEvent(const Event& event) = 0;
- virtual ~Observer() = default;
- };
- // 具体观察者
- class ConcreteObserver : public Observer {
- public:
- void handleEvent(const Event& event) override {
- std::cout << "Observer received event of type: " << static_cast<int>(event.type)
- << " with data: " << event.data << std::endl;
- }
- };
- // 被观察者接口
- class Subject {
- private:
- std::map<EventType, std::vector<Observer*>> eventObservers;
- public:
- void attach(EventType type, Observer* observer) {
- eventObservers[type].push_back(observer);
- }
- void detach(EventType type, Observer* observer) {
- auto& observers = eventObservers[type];
- observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
- }
- void notify(const Event& event) {
- auto& observers = eventObservers[event.type];
- for (Observer* observer : observers) {
- observer->handleEvent(event);
- }
- }
- void changeState(const std::string& state) {
- std::cout << "Subject state changed." << std::endl;
- notify(Event(EventType::StateChanged, state));
- }
- void updateData(const std::string& data) {
- std::cout << "Subject data updated." << std::endl;
- notify(Event(EventType::DataUpdated, data));
- }
- };
- int main() {
- Subject subject;
- ConcreteObserver observer1;
- ConcreteObserver observer2;
- subject.attach(EventType::StateChanged, &observer1);
- subject.attach(EventType::DataUpdated, &observer2);
- subject.changeState("New State");
- subject.updateData("New Data");
- subject.detach(EventType::StateChanged, &observer1);
- subject.changeState("Another State");
- return 0;
- }
复制代码
4. 观察者队列(Observer Queue)
在观察者队列中,使用队列来管理观察者,当被观察者状态变化时,将通知放入队列中,观察者从队列中取出通知进行处理。
示例代码
- #include <iostream>
- #include <queue>
- #include <string>
- #include <mutex>
- #include <thread>
- #include <condition_variable>
- // 通知类型
- class Notification {
- public:
- virtual void process() = 0;
- virtual ~Notification() = default;
- };
- // 具体通知
- class ConcreteNotification : public Notification {
- private:
- std::string message;
- public:
- ConcreteNotification(const std::string& message) : message(message) {}
- void process() override {
- std::cout << "Processing notification: " << message << std::endl;
- }
- };
- // 观察者队列
- class ObserverQueue {
- private:
- std::queue<Notification*> queue;
- std::mutex mutex;
- std::condition_variable cv;
- public:
- void enqueue(Notification* notification) {
- std::lock_guard<std::mutex> lock(mutex);
- queue.push(notification);
- cv.notify_one();
- }
- void processQueue() {
- while (true) {
- std::unique_lock<std::mutex> lock(mutex);
- cv.wait(lock, [this] { return !queue.empty(); });
- Notification* notification = queue.front();
- queue.pop();
- lock.unlock();
- notification->process();
- delete notification;
- }
- }
- };
- int main() {
- ObserverQueue queue;
- std::thread worker([&queue]() { queue.processQueue(); });
- queue.enqueue(new ConcreteNotification("Notification 1"));
- queue.enqueue(new ConcreteNotification("Notification 2"));
- queue.enqueue(new ConcreteNotification("Notification 3"));
- worker.join();
- return 0;
- }
复制代码
5. 弱引用观察者(Weak Reference Observer)
在弱引用观察者中,使用弱引用(Weak Reference)来管理观察者,防止观察者对象未被开释时导致的内存泄漏。
示例代码
- #include <iostream>
- #include <vector>
- #include <memory>
- #include <string>
- #include <functional>
- // 观察者接口
- class Observer {
- public:
- virtual void update(const std::string& message) = 0;
- virtual ~Observer() = default;
- };
- // 具体观察者
- class ConcreteObserver : public Observer {
- public:
- void update(const std::string& message) override {
- std::cout << "Observer received message: " << message << std::endl;
- }
- };
- // 被观察者接口
- class Subject {
- public:
- virtual void attach(std::weak_ptr<Observer> observer) = 0;
- virtual void notify(const std::string& message) = 0;
- virtual ~Subject() = default;
- };
- // 具体被观察者
- class ConcreteSubject : public Subject {
- private:
- std::vector<std::weak_ptr<Observer>> observers;
- public:
- void attach(std::weak_ptr<Observer> observer) override {
- observers.push_back(observer);
- }
- void notify(const std::string& message) override {
- observers.erase(std::remove_if(observers.begin(), observers.end(),
- [](const std::weak_ptr<Observer>& observer) {
- return observer.expired();
- }), observers.end());
- for (auto& observer : observers) {
- if (auto sharedObserver = observer.lock()) {
- sharedObserver->update(message);
- }
- }
- }
- void changeState(const std::string& message) {
- std::cout << "Subject state changed. Notifying observers..." << std::endl;
- notify(message);
- }
- };
- int main() {
- ConcreteSubject subject;
- auto observer1 = std::make_shared<ConcreteObserver>();
- auto observer2 = std::make_shared<ConcreteObserver>();
- subject.attach(observer1);
- subject.attach(observer2);
- subject.changeState("Hello Observers!");
- observer1.reset(); // 释放 observer1
- subject.changeState("Hello again!");
- return 0;
- }
复制代码
总结
以上是观察者模式的几种差别变体的C++代码示例。每种变体都有其适用的场景和优缺点,开发者可以根据具体的需求选择合适的实现方式。观察者模式的焦点思想是解耦对象之间的关系,并通过通知机制实现对象之间的通讯。
基于观察者模式特点的软件架构模式
观察者模式的特性使得它在许多软件架构中都有重要的应用,以下是几种基于观察者模式特点的软件架构模式:
- 发布-订阅模式(Publish-Subscribe Pattern):
- 特点:发布-订阅模式是观察者模式的一种扩展,它将消息的发送者(发布者)和接收者(订阅者)完全解耦。发布者不必要知道订阅者的存在,订阅者也不必要知道发布者的存在。
- 应用:常见的应用场景包罗消息队列体系(如 Kafka、RabbitMQ)、事件驱动体系等。
- 优点:体系组件之间的耦合度极低,适合构建分布式体系。
- 事件驱动架构(Event-Driven Architecture):
- 特点:事件驱动架构是一种基于事件的架构模式,体系中的组件通过事件进行通讯。事件的产生和处理通常基于观察者模式。
- 应用:常见的应用场景包罗图形用户界面、分布式体系、微服务架构等。
- 优点:体系组件可以异步处理事件,进步体系的可扩展性和响应性。
- 模型-视图-控制器(MVC)模式:
- 特点:MVC模式将应用步伐分为三个部分:模型(Model)、视图(View)和控制器(Controller)。模型是观察者模式中的被观察者,视图是观察者。当模型的状态发生变化时,视图会主动更新。
- 应用:常见的应用场景包罗Web应用步伐、桌面应用步伐等。
- 优点:模型和视图之间的解耦,使得体系更易于维护和扩展。
- 观察者-被观察者链(Observer-Observable Chain):
- 特点:在这种架构中,观察者和被观察者可以形成一个链式结构,每个被观察者可以同时是观察者。
- 应用:常见的应用场景包罗事件流传链、责任链模式等。
- 优点:可以实现复杂的事件流传和处理机制。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |