最近学习到设计模式,现总结个人学习观察者模式内容【注重的是自动通知它的依赖对象】。
上一篇:Java设计模式-迭代器模式
定义
指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
优缺点
优点
- 观察者和被观察者是抽象耦合的。
- 建立一套触发机制。
缺点
- 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化【只知道变化的结果,不知变化过程】。
实现
观察者模式的主要角色如下。
- 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
- 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
- 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
- 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
我们以最
新新型病毒为例。
代码
观察者以及具体观察者【观察者有多个】
/** 这里已当下新冠病毒为描述,这里定义了每一天关注每个国家数据更新情况
* 观察者接口/抽象类,定义了具体的抽象行为
* @author cc百川
*/
public interface Observer {
//每一天数据更新
public void update(String countryName, String desc);
//推送给每一个用户
public void showMsg(String countryName, String desc);
}
/** 我们常用支付宝查看一些热点信息
* 阿里观察者【例如我们目前每天查看新冠病毒信息】
* @author cc百川
*/
class AlipayObservice implements Observer{
@Override //后台数据更新了
public void update(String countryName, String desc) {
showMsg(countryName, desc);
}
@Override //数据需要显示给用户
public void showMsg(String countryName, String desc) {
System.out.println("支付宝提供视图:"+countryName+" 现存新冠病毒描述:"+desc);
}
}
/**
* 微信观察者【相信很多小伙伴都是从丁香园中查看疫情最新情况的吧】
* @author cc百川
*/
class WeChatObservice implements Observer {
@Override
public void update(String countryName, String desc) {
showMsg(countryName, desc);
}
@Override
public void showMsg(String countryName, String desc) {
System.out.println("微信提供视图:"+countryName+" 现存新冠病毒描述:"+desc);
}
}
Subject 对象带有绑定观察者到 Client 对象和从 Client
对象解绑观察者的方法【数据总台,一份(这里转发给观察者数据变化结果)】
/**
* 抽象主题,定义了抽象行为,为后面的实现类定义了规则
* @author cc百川
*/
public abstract class Subject {
public abstract void register(Observer o);
public abstract void remove(Observer o);
public abstract void loopList();
}
/**
* 数据总台【例如国家卫健委,每天都在发布最新消息】
* @author cc百川
*/
class DataTerminal extends Subject{
private List<Observer> list;//存放所有的观察者
private String name;//缓存名称,便于通知
private String desc;//缓存描述,便于通知
public DataTerminal() {this.list = new ArrayList<>();}
//更新数据【发布最新情况】
public void update(String counname,String desc){
this.name = counname;
this.desc = desc;
loopList();
}
@Override //注册新的对象
public void register(Observer o) { list.add(o); }
@Override //移出一个对象
public void remove(Observer o) { list.remove(o); }
@Override //遍历所有具体观察者,发出修改数据的通知
public void loopList() {
for(Observer obs : list){
obs.update(this.name, this.desc);
}
}
}
测试
public class Test {
public static void main(String[] args) {
DataTerminal dt = new DataTerminal();//数据总台
//添加阿里观察者
dt.register(new AlipayObservice());
//微信观察者
dt.register(new WeChatObservice());
System.out.println("-----------2020.3.31-----------------");
dt.update("中国", "现存本土患者约0人,境外输入1人");
dt.update("日本", "现存本土患者约500人,境外输入1人");
System.out.println("------------2020.4.1----------------");
dt.update("中国", "现存本土患者约0人,境外输入0人");
dt.update("日本", "现存本土患者约1000人,境外输入0人");
}
}
观察者模式重点在于,通过数据控制台转发用户的消息给每一个控制台下的观察者。【即这里的数据Test通过DataTerminal 把自己修改后的消息,发送给每一个具体的Observer】
以上仅为个人学习,如果错误望指出,谢谢。