观察者模式是一种软件设计模式。
一、定义与概念
在观察者模式中,存在被观察的对象(主题)和观察这个对象的观察者。主题在自身状态发生变化时,会通知所有注册的观察者,让它们能够做出相应的反应。
二、作用与优势
-
- 解耦:主题和观察者之间的依赖关系被弱化,它们之间通过抽象接口进行交互,使得双方的变化不会直接影响到对方,提高了系统的可维护性和可扩展性。
-
- 灵活性:可以在运行时动态地添加、删除观察者,方便系统的扩展和维护。
-
- 提高响应性:当主题状态发生变化时,能够及时通知所有观察者,使得系统能够快速做出反应。
三、应用场景
-
- 图形用户界面:例如按钮的点击事件可以被多个组件观察,当按钮被点击时,这些组件可以做出相应的反应。
-
- 消息通知系统:当有新消息时,通知所有订阅了该消息的用户。
-
- 股票交易系统:股票价格变化时,通知所有关注该股票的投资者。
四、代码实现
观察者模式主要涉及到两个角色:观察者(Observer)和被观察对象(Subject)。以下是观察者模式的类图描述:
一、被观察对象(Subject)
属性:
- 通常有一个或多个观察者列表,用于存储注册的观察者对象。
方法:
- attach(Observer observer):用于将观察者添加到观察者列表中。
- detach(Observer observer):从观察者列表中移除指定的观察者。
- notifyObservers():当被观察对象的状态发生变化时,通知所有注册的观察者。
二、观察者(Observer)
• 方法:
- update():当被观察对象状态变化时,被观察对象会调用此方法通知观察者,观察者在这个方法中进行相应的处理。
观察者模式通过这种方式实现了对象之间的一对多依赖关系,当被观察对象的状态发生变化时,所有依赖它的观察者都会收到通知并进行相应的更新。
以下是用 C++实现观察者模式的示例代码:
cpp
#include <iostream>
#include <vector>
#include <algorithm>
// 抽象观察者类
class Observer {
public:
virtual void update() = 0;
};
// 抽象主题类
class Subject {
public:
virtual void attach(Observer* observer) = 0;
virtual void detach(Observer* observer) = 0;
virtual void notify() = 0;
};
// 具体主题类
class ConcreteSubject : public Subject {
private:
int state;
std::vector<Observer*> observers;
public:
ConcreteSubject() : state(0) {}
void setState(int newState) {
state = newState;
notify();
}
int getState() const {
return state;
}
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 ConcreteObserver : public Observer {
private:
ConcreteSubject* subject;
public:
ConcreteObserver(ConcreteSubject* sub) : subject(sub) {
subject->attach(this);
}
void update() override {
int state = subject->getState();
std::cout << "Observer notified. New state: " << state << std::endl;
}
};
int main() {
ConcreteSubject* subject = new ConcreteSubject();
ConcreteObserver* observer1 = new ConcreteObserver(subject);
ConcreteObserver* observer2 = new ConcreteObserver(subject);
subject->setState(10);
subject->setState(20);
delete observer2;
subject->setState(30);
delete observer1;
delete subject;
return 0;
}
在这个示例中,Subject是抽象主题类,ConcreteSubject是具体主题类,Observer是抽象观察者类,ConcreteObserver是具体观察者类。具体主题的状态变化时会通知所有注册的观察者。