(个人笔记,不喜勿喷,欢迎指正~)
一、概念
观察者模式:定义了对象之间一对多依赖,这样一来,当一个对象状态改变时。它的所有的依赖都会收到通知并自动更新。
内容理解:
我们定义的对象A和对象集合Bn{B1,B2,B3,...}。存在依赖关系:A发生改变,Bn集合中的B1,B2,B3发生响应,各自同步内容更新。保证Bn集合内的各自内容与A中的内容,保持运行范围内的一致。(Ps:不难发现我们所谓的观察者,对所观察内容是被动获取信息的。)
二、设计原则
1、针对接口编程,而不是针对实现编程。
2、为了交互对象之间的松耦合设计而努力;
三、类图
类图理解:
1、由于观察者被动接受消息,我们需要Bn域的所有子项观察者有一个消息接口 observer,向主题暴露方法excute();
2、主题必须向观察者提供“注册”板块提供,给予观察者提供登记;为此,遵循设计原则1,我们抽象出注册业务的接口,使得主题具备业务注册能力;注册后的观察者,才具备接受此主题推送更新信息的福利。
3、主题应该向观察者应是送耦合;不关心观察者对信息使用情况,故而全体信息推送,选择推送自身对象作为参数;主题只需要暴露出服务内容的API(getContents);观察者自行实现内容;(ps:达到了松耦合的目的)
4、状态stat,应该理解为状态控制开关,提供开关的好处是,自定义策略完成开关的开启与关闭,达到推送策略。
四、代码实现
/**
* 观察者模式
* @author Ws Zhuang
*
*/
public class ObserverTest {
public static void main(String[] args) {
Subject sb =new Subject();
ObserverA a =new ObserverA(sb); //将a 初始化主题sb的观察员
sb.setContents("我是Mr zhuang");
System.out.println();
sb.notifyObserver();
sb.setContents("我是Mr Li");
System.out.println();
sb.notifyObserver();
sb.setContents("我是Mr zheng");
System.out.println();
sb.notifyObserver();
}
}
/**
* 观察者抽象接口
*/
interface Observer {
/**
* 响应消息的能力
* @param observable
*/
void excute(Observable observable);
}
/**
* 观察员A
*/
class ObserverA implements Observer{
private String lastContents;
private String contents;
public ObserverA(Observable observable) {
if(observable ==null)
{
throw new RuntimeException("observable can not be null!");
}
observable.register(this);
}
@Override
public void excute(Observable observable) {
if(observable instanceof Subject){
Subject sb =(Subject) observable;
lastContents =contents;
contents =sb.getContents();
}
System.out.println("观察者输出 上一次内容 : "+lastContents);
System.out.println("观察者输出 更新后内容 : "+contents);
}
}
/**
* 具备推送业务能力的接口
* @author Ws zhuang
*
*/
interface Observable {
void register(Observer observer);
void logOff(Observer observer);
void notifyObserver();
}
/**
* 主题
*/
class Subject implements Observable{
private Vector<Observer> observers =new Vector<>();
private String contents ;
private boolean stat =false;
public void setContents(String contents) {
this.contents = contents;
stat =true;//改变状态
}
public String getContents() {
return contents;
}
@Override
public void register(Observer observer) {
observers.add(observer);
}
@Override
public void logOff(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObserver() {
if(stat)
{
observers.forEach(observer ->
{observer.excute(this); });
}
stat =false;//改变状态
}
}
测试结果:
五、总结:
观察者模式,其实在概念中已经很明显说清使用场景;据说JDK中很常使用。目前源码看的少,希望以后有时间去深入学习源码内容。坚持写写笔记~恩,你等的人,也同样渴望你变得更加优秀~~。大器晚成没关系~~