导航
- 一、行为描述
- 二、角色关系
- 三、代码示例
一、行为描述
观察者会观察特定对象的状态变化,一旦状态有所变化或产生特定条件,被观察对象会通知给观察者,
而观察者则会依据通知信息采取特定处理措施。
举个例子,公司接到了一个大项目,各个部门都在观察项目的进度,一旦洽谈成功,项目正式进入启动阶段,
那么设计部就会出图纸,开发部就会出流程、出架构,售前部就会跑现场实地勘测…
项目就是被观察者,而各个部门就是观察者。
二、角色关系
观察者模式就两种角色——观察者和被观察者。
观察者对象往往会规范结构,一般是继承一个抽象观察者。
I. 抽象观察者会定义3个重要内容:
- 被观察对象的引用
- 构造函数——赋值被观察者、将this加入观察席
- 通知函数
II. 子类观察者仅调用父类构造,并实现通知函数即可。
III. 被观察者需要定义 4 个重要内容:
- 状态变量。这是观察者存在的目的和关键。
- 观察席。简单的说就是一个容纳观察者对象的容器,可以是List、也可以是Map,甚至是数组。
- 入席函数。观察者应该在构造的时候通过入席函数将自身加入到观察席容器中。
- 广播函数。与观察者的通知函数一样,被观察者应该在状态变化时(可以是 setter 函数)调用观察席中各个观察者的通知方法。
三、代码示例
抽象观察者:
/*** 观察者*/
@Data
public abstract class Observer {/*** 被观察对象*/protected ObserveTarget target;/*** 构造观察者时,直接建立观察者与被观察者的关系*/public Observer(ObserveTarget target) {this.target = target;target.getObservers().add(this);}/*** 接收广播消息*/abstract void recvMsg();
}
观察者1、观察者2:
/*** 观察者1号*/
public class Observer1 extends Observer {public Observer1(ObserveTarget target) {super(target);}@Overridevoid recvMsg() {System.out.println("Observer1-state = " + target.getState());}
}
/*** 观察者2号*/
public class Observer2 extends Observer {public Observer2(ObserveTarget target) {super(target);}@Overridevoid recvMsg() {// 观察者可以视情况选择性处理接收的消息if (target.getState() == 1)System.out.println("Observer2-state = " + target.getState());}
}
被观察者:
/*** 被观察目标*/
@Data
public class ObserveTarget {/*** 状态变量*/private volatile int state;/*** 观察席(观察者容器)*/private Collection<Observer> observers = new ArrayList<>();/*** 入席函数(新增观察者)*/public void addObserver(Observer observer) {observers.add(observer);}public void setState(int state) {this.state = state;// 发送广播通知broadcast();}/*** 广播函数*/private void broadcast() {observers.forEach(o -> o.recvMsg());}
}
测试代码:
public class TestObserve {public static void main(String[] args) {ObserveTarget target = new ObserveTarget();Observer1 observer1 = new Observer1(target);Observer2 observer2 = new Observer2(target);target.setState(1);target.setState(2);target.setState(3);}
}
// output:
Observer1-state = 1
Observer2-state = 1
Observer1-state = 2
Observer1-state = 3