博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
观察者模式
阅读量:6851 次
发布时间:2019-06-26

本文共 2721 字,大约阅读时间需要 9 分钟。

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有的观察者对象,让他们可以自动更新自己。

观察者模式的类图:

  • 抽象主题(Subject):主题对象可以把所有的观察者对象保存在一个容器中,并且抽象主题提供删除和注册观察者的方法。
  • 抽象观察者(Observer):是所有具体的观察者的接口,在得到抽象主题发生变化时更新自己的状态。
  • 具体主题(ConcreteSubject):在具体主题的内部状态发生变化时,给所有登记过的观察者发出通知。
  • 具体观察者(ConcreteObserver):存储于主题相符的状态,具体观察者实现抽象观察者的更新方法。
抽象主题:
public interface Subject {	//注册观察者	public void attach(Observer observer);		//移除观察者	public void remove(Observer observer);		//通知所有观察者已经更新状态	void notifyAllObserver();}
具体主题:
public class ConcreteSubject implements Subject {	private int state;	public int getState() {		return state;	}	public void setState(int state) {		this.state = state;		// 主题状态改变,通知所有观察者		this.notifyAllObserver();	}	// 使用ArrayList管理观察者	private ArrayList
list = new ArrayList
(); @Override public void attach(Observer observer) { list.add(observer); } @Override public void remove(Observer observer) { list.remove(observer); } @Override public void notifyAllObserver() { // 通知所有观察者 for (Observer o : list) { o.update(this); } }}
抽象观察者:
public interface Observer {	// 更新状态	public void update(Subject subject);}
具体观察者:
public class ConcreteObserver implements Observer {	private int myState;	private String myName;	public ConcreteObserver(String _name) {		this.myName = _name;	}	@Override	public void update(Subject subject) {		// 得到状态		myState = ((ConcreteSubject) subject).getState();		System.out.println("观察者: " + this.myName + ":--->" + myState);	}}
客户端类:
public class Client {	public static void main(String[] args) {		// 得到具体主题		ConcreteSubject cs = new ConcreteSubject();		ConcreteObserver co1 = new ConcreteObserver("观察者甲");		ConcreteObserver co2 = new ConcreteObserver("观察者乙");		ConcreteObserver co3 = new ConcreteObserver("观察者丙");		// 注册观察者		cs.attach(co1);		cs.attach(co2);		cs.attach(co3);		System.out.println("具体主题状态改变为 3");		System.out.println("******************");		cs.setState(3);		System.out.println("具体主题状态改变为 6");		System.out.println("******************");		cs.setState(6);	}}
运行客户端类控制台会输出以下结果:
具体主题状态改变为 3******************观察者: 观察者甲:--->3观察者: 观察者乙:--->3观察者: 观察者丙:--->3具体主题状态改变为 6******************观察者: 观察者甲:--->6观察者: 观察者乙:--->6观察者: 观察者丙:--->6
使用观察者模式应该重点注意两个问题:
  1. 广播链的问题: 如果一个对象既是观察者也是被观察者,比如数据库中的触发器,A表插入数据后,B表会同时插入数据;B表插入数据后,C表会同时插入数据......这样数据库基本就毁掉了!建议在观察者模式中,最多出现一个对象同时作为观察者和被观察者(消息最多传递两次)。
  2. 异步处理问题:如果观察者很多,处理时间比较长,只能采用异步处理的方式,这是需要考虑线程安全以及队列的问题。
观察者模式的优缺点:
优点:
  1. 观察者模式在观察者和被观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者的聚集,每一个具体观察者都符合抽象观察者的接口。被观察者并不“认识”具体的观察者。
  2. 观察者模式支持广播通信,被观察者会向所有登记过的观察者发出通知。
缺点:
  1. 如果一个被观察者有很多直接或者间接的观察者,一一通知观察者会花费很多时间。
  2. 如果被观察者之间存在循环依赖,那么会出现循环调用,导致系统崩溃。
  3. 如果被观察者通知观察者是采用其他线程进行时,应该避免线程安全问题。
  4. 观察者虽然可以知道被观察者发生变化,但是不能知晓具体是怎么发生变化的。

转载于:https://www.cnblogs.com/xpeng-V/p/7349680.html

你可能感兴趣的文章
LeetCode - Nth Highest Salary
查看>>
9.ORM数据访问
查看>>
在RHEL5下搭建SSH远程登录服务器
查看>>
使用Moblin SDK开发应用程序 -- Image Creator
查看>>
【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记14 视图绘制Demo
查看>>
/dev/null &
查看>>
在Ubuntu上安装Node.js的Upstream版本
查看>>
扩展GridView控件(8) - 导出数据源的数据为Excel、Word或Text
查看>>
CISCO路由器配置基础(3)
查看>>
linux下通过串口登陆交换机
查看>>
微信公众平台群发规则说明
查看>>
LINUX下直接使用ISO文件
查看>>
第四章 apache的工作模式
查看>>
mysql备份和恢复总结
查看>>
软件明明已经删除 控制面板里还有名称
查看>>
深入浅出的SQL server 查询优化
查看>>
Hyper-V vNext新的虚拟机配置文件、配置版本
查看>>
通俗易懂,各常用线程池的执行 流程图
查看>>
CentOS 6.4 安装python2.7/mysqldb/ipython
查看>>
hive0.11 hiveserver custom认证bug
查看>>