设计模式-观察者模式
# 设计模式-观察者模式
# 概述
汽车驾驶员看到红灯的时候会停止,看到绿灯的时候会前进。那么信号灯就是汽车驾驶员的观察目标,而汽车驾驶员就是观察者。当信号灯变化的时候,驾驶员的行为也会随之发生变化。
# 定义
一个对象行为的改变可能会导致一个或多个其他与之存在依赖关系的对象行为发生改变。观察者模式用户描述对象之间的依赖关系,为实现多个对象之间的联动提供了一种解决方案。
观察者模式: 定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时其相关依赖对象得到通知并被自动更新。
# 观察者模式结构
观察者模式包含以下4个角色:
目标(Subject)角色:它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
具体目标(Concrete Subject)角色:它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
# 观察者模式案例
1、创建目标
public class Subject {
private final List<Observer> observers = new ArrayList<>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
public void attach(Observer observer) {
observers.add(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
2、创建抽象观察者
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
3、创建具体观察者
public class BinaryObserver extends Observer {
public BinaryObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("Binary String: " + Integer.toBinaryString(subject.getState()));
}
}
public class HexObserver extends Observer {
public HexObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("Hex String: " + Integer.toHexString(subject.getState()).toUpperCase());
}
}
public class OctalObserver extends Observer {
public OctalObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("Octal String: " + Integer.toOctalString(subject.getState()));
}
}
4、案例实现
public class ObserverPatternDemo {
public static void main(String[] args) {
Subject subject = new Subject();
new HexObserver(subject);
new OctalObserver(subject);
new BinaryObserver(subject);
System.out.println("First state change: 15");
subject.setState(15);
System.out.println("Second state change: 10");
subject.setState(10);
}
}
// 输出
First state change: 15
Hex String: F
Octal String: 17
Binary String: 1111
Second state change: 10
Hex String: A
Octal String: 12
Binary String: 1010
# 观察者模式优缺点
优点:
- 可以实现表示层和数据逻辑层的分离,定义了稳定的消息更新传递机制。
- 在观察目标和观察者之间建立一个抽象的耦合。
- 支持广播通信。
缺点:
如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
# 观察者模式适用环境
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使他们可以各自独立地改变和复用。
- 一个对象的改变将导致一个或多个其他对象也发生改变,而并不知道具体有多少对象将发生改变。
# 参考
Java设计模式
上次更新: 2024/06/29, 15:13:44