设计模式(20)-观察者模式及实现
基本概念
核心思想是定义一种一对多的依赖关系,使得一个主题(通常称为被观察者)可以同时维护多个观察者,并在其状态改变时自动通知所有观察者。这样,观察者无需关心主题的内部实现细节,而只需要关心主题的状态变化。在实现中,通常会定义一个抽象的主题类和一个抽象的观察者类,具体的主题和观察者类会继承这些抽象类并实现相应的方法。
优点:
● 松耦合:主题和观察者之间的耦合度降低,使得它们可以独立地进行变化。
● 可扩展性:可以方便地增加新的观察者,而不会影响到已有的观察者和主题。
● 自动通知:主题状态改变时会自动通知观察者,减少手动维护通知的工作。
● 可重用性:主题和观察者可以在不同的场景中重复使用。
缺点:
● 可能引起性能问题:如果观察者过多或通知机制不合理,可能会导致性能下降。
● 更新顺序问题:观察者的更新顺序可能会影响到系统的行为,需要特别注意。
● 过度使用的风险:并不是所有的状态变化都适合使用观察者模式,过度使用可能导致代码复杂化。
https://gitee.com/want-to-lose-another-30-jin/design-pattern-implementation
设计模式具体实现
角色
1、主题(Subject):
也被称为“观察目标”,它维护了一组观察者,并提供接口供观察者注册和注销自己。
2、观察者(Observer):
定义了一个更新接口,使得在主题状态发生变化时,可以接收到通知。
3、具体主题(Concrete Subject):
维护当前状态,当状态改变时,给所有注册过的观察者发送通知。
4、具体观察者(Concrete Observer):
存储与主题相关的状态,当接收到主题的更新通知时,更新自己的状态。
java实现
package shejimoshi.guanchazhemoshi;
// 主题接口
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
package shejimoshi.guanchazhemoshi;
// 观察者接口
public interface Observer {
void update(String message);
}
package shejimoshi.guanchazhemoshi;
import java.util.ArrayList;
import java.util.List;
// 具体主题
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int index = observers.indexOf(o);
if (index >= 0) {
observers.remove(index);
}
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
public void setState(String state) {
this.state = state;
notifyObservers();
}
public String getState() {
return state;
}
}
package shejimoshi.guanchazhemoshi;
public class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received update: " + message);
}
}
package shejimoshi.guanchazhemoshi;
public class client {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver("Observer 1");
ConcreteObserver observer2 = new ConcreteObserver("Observer 2");
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.setState("New State"); // 触发通知
subject.removeObserver(observer1);
subject.setState("Another State"); // 触发通知,observer1 不会收到
}
}
c++实现
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
// 观察者接口
class Observer {
public:
virtual ~Observer() {}
virtual void update(const std::string& message) = 0;
};
// 主题接口
class Subject {
private:
std::vector<Observer*> observers;
public:
virtual ~Subject() {}
void registerObserver(Observer* o) {
observers.push_back(o);
}
void removeObserver(Observer* o) {
observers.erase(std::remove(observers.begin(), observers.end(), o), observers.end());
}
void notifyObservers() {
for (Observer* observer : observers) {
observer->update("Updated State");
}
}
};
// 具体主题
class ConcreteSubject : public Subject {
private:
std::string state;
public:
void setState(const std::string& state) {
this->state = state;
notifyObservers();
}
};
// 具体观察者
class ConcreteObserver : public Observer {
private:
std::string name;
public:
ConcreteObserver(const std::string& name) : name(name) {}
void update(const std::string& message) override {
std::cout << name << " received update: " << message << std::endl;
}
};
// 客户端
int main() {
ConcreteSubject subject;
ConcreteObserver observer1("Observer 1");
ConcreteObserver observer2("Observer 2");
subject.registerObserver(&observer1);
subject.registerObserver(&observer2);
subject.setState("New State"); // 触发通知
subject.removeObserver(&observer1);
subject.setState("Another State"); // 触发通知,observer1 不会收到
return 0;
}