18.(行为型模式)java设计模式之观察者模式
一、什么是观察者模式
定义对象间⼀种⼀对多的依赖关系,使得每当⼀个对象改变状态,则所有依赖于它的对象都会得到通知并⾃动更新,也叫做发布订阅模式Publish/Subscribe,属于⾏为型模式
二、观察者模式的实现方式
模式结构分析:
Subject主题:持有多个观察者对象的引⽤,抽象主题提供了⼀个接⼝可以增加和删除观察者对象;有⼀个观察者数组,并实现增、删及通知操作。
Observer抽象观察者:为具体观察者定义⼀个接⼝,在得到主题的通知时更新⾃⼰。
ConcreteSubject具体主题:将有关状态存⼊具体观察者对象,在具体主题内部状态改变时,给所有登记过的观察者发出通知。
ConcreteObserver具体观察者:实现抽象观察者⻆⾊所要求的更新接⼝,以便使本身的状态与主题的状态保持⼀致。
类关系图:
统一模型:
代码实现:
查看代码
/*
* 抽象主题
* */
public class Subject {
private List<Observer> observerList = new ArrayList<>();
/*
* 新增观察者
* */
public void addObserver(Observer observer) {
this.observerList.add(observer);
}
/**
* 删除观察者
*
* @param observer
*/
public void deleteObserver(Observer observer) {
this.observerList.remove(observer);
}
/*
* 通知所有的观察者
* */
public void notifyAllObserver() {
for (Observer observer : this.observerList) {
observer.update();
}
}
}
/*
*
* 老板完成工作,开始视察下属的工作情况
* */
public class BossConcreteSubject extends Subject {
public void dosomething() {
System.out.println("老板完成自己的工作");
//还有其他操作
System.out.println("视察公司工作情况");
super.notifyAllObserver();
}
}
/*
* 抽象观察者
* */
public interface Observer {
//接受到变更通知之后,进行正常的处理
void update();
}
/*
* LW接受到通知
* */
public class LWConcreteObserver implements Observer {
@Override
public void update() {
System.out.println("⽼王发现领导到来,暂停在线摸⻥,回归⼯作");
}
}
/*
* 安娜接受到通知
* */
public class AnnaConcreteObserver implements Observer{
@Override
public void update() {
System.out.println("Anna发现领导到来,暂停在线摸⻥,回归⼯作");
}
}
测试用例:
/*
* 观察者模式
* */
@Test
public void observer(){
//创建⼀个主题,⽼板
BossConcreteSubject subject = new BossConcreteSubject();
//创建观察者,就是摸⻥的同事
Observer lwObserver = new LWConcreteObserver();
//创建观察者,就是摸⻥的同事
Observer annaObserver = new AnnaConcreteObserver();
//建⽴对应的关系,⽼板这个主题被同事进⾏观察
subject.addObserver(lwObserver);
subject.addObserver(annaObserver);
//主题开始活动,⾥⾯会通知观察者(相当于发布消息)
subject.dosomething();
}
测试结果:
老板完成自己的工作
视察公司工作情况
⽼王发现领导到来,暂停在线摸⻥,回归⼯作
Anna发现领导到来,暂停在线摸⻥,回归⼯作
方法评估:
优点:
- 降低了⽬标与观察者之间的耦合关系,⽬标与观察者之间建⽴了⼀套触发机制。
- 观察者和被观察者是抽象耦合的。
缺点:
- 观察者和观察⽬标之间有循环依赖的话,会触发它们之间进⾏循环调⽤,可能导致系统崩溃。
- ⼀个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。