设计模式学习笔记——观察者模式
2016-03-17 11:31
453 查看
观察者模式
观察者模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。结构图
代码实现
抽象观察者Observer:根据被观察者动作,做出相应动作。/** * 抽象观察者类 * @author xukai * 2016年3月16日 下午11:33:10 */ public abstract class Observer { /** * 做出相应 */ public abstract void update(); }抽象被观察者Subject:被观察,可以选择通过某个观察者,也可以不通知
/** * 抽象被观察者 * @author xukai * 2016年3月16日 下午11:43:21 */ public abstract class Subject { private Vector<Observer> observers = new Vector<>(); public void attach(Observer observer){ observers.add(observer); } public void detach(Observer observer){ observers.remove(observer); } public void notifyObserver(){ for(Observer o : observers){ o.update(); } } }具体被观察者ConcreteSubject:
/** * 具体被观察者 * @author xukai * 2016年3月16日 下午11:46:37 */ public class ConcreteSubject extends Subject { private String subjectState; public String getSubjectState() { return subjectState; } public void setSubjectState(String subjectState) { this.subjectState = subjectState; } }具体观察者ConcreteObserver:
/** * 具体观察者 * * @author xukai 2016年3月16日 下午11:37:20 */ public class ConcreteObserver extends Observer { private String name; private String observerState; private ConcreteSubject subject; public ConcreteSubject getSubject() { return subject; } public void setSubject(ConcreteSubject subject) { this.subject = subject; } public ConcreteObserver(ConcreteSubject subject, String name) { this.subject = subject; this.name = name; } @Override public void update() { observerState = subject.getSubjectState(); System.out.println("观察者"+ name +"的状态:" + observerState); } }客户端:
public class Client { public static void main(String[] args) { ConcreteSubject s = new ConcreteSubject(); s.attach(new ConcreteObserver(s, "A")); s.attach(new ConcreteObserver(s, "B")); s.setSubjectState("ABC"); s.notifyObserver(); } }控制台:
观察者A的状态:ABC 观察者B的状态:ABC可以看到根据被观察者的通知,可以修改观察者相应的信息。
demo
问题:公司中,老板有事外出,员工有的炒股,有的看NBA比赛,员工请求前台小妹通知老板回来。结构图
代码实现
抽象通知者类Subject:import java.util.Vector; /** * 抽象通知者,即被观察者 * * @author xukai 2016年3月17日 上午9:40:26 */ public abstract class Subject { protected String name; protected String state; public Subject(String name, String state) { this.name = name; this.state = state; } Vector<Observer> observers = new Vector<>(); public void attacth(Observer observer) { observers.add(observer); } public void detach(Observer observer) { observers.remove(observer); } public void notifyObserver() { System.out.println(name + "说:" + state); for (Observer o : observers) { o.update(); } } }抽象观察者类Observer:
/** * 抽象观察者,对通知者做出响应 * * @author xukai 2016年3月17日 上午9:39:03 */ public abstract class Observer { private String name; protected Subject subject; protected String doing; public Observer(String name, Subject subject) { this.name = name; this.subject = subject; } public String getName() { return name; } public void setName(String name) { this.name = name; } public abstract void update(); @Override public String toString() { return name + doing; } }具体通知者类Boss:
/** * 老板类,继承通知者 * * @author xukai 2016年3月17日 上午9:45:03 */ public class Boss extends Subject { public Boss(String name, String state) { super(name, state); } }具体通知者类:
/** * 前台通知者 * @author xukai * 2016年3月17日 上午10:25:47 */ public class ReceptionGirl extends Subject { public ReceptionGirl(String name, String state) { super(name, state); } }看NBA的观察者:
/** * 具体观察者,喜爱看NBA * @author xukai * 2016年3月17日 上午9:57:21 */ public class EmployeeNBAObserver extends Observer { public EmployeeNBAObserver(String name, Subject subject) { super(name, subject); } @Override public void update() { if(super.subject.state == "出去了"){ super.doing = ",看NBA比赛..."; }else if(super.subject.state == "回来了"){ super.doing = ",停止看比赛,开始工作..."; } System.out.println(super.getName() + super.doing); } }炒股的观察者:
/** * 具体观察者,喜爱看股票 * @author xukai * 2016年3月17日 上午10:00:23 */ public class EmployeeStockObserver extends Observer { public EmployeeStockObserver(String name, Subject subject) { super(name, subject); } @Override public void update() { if(super.subject.state == "出去了"){ super.doing = ",看股票市场..."; }else if(super.subject.state == "回来了"){ super.doing = ",停止看股票,开始工作..."; } System.out.println(super.getName() + super.doing); } }客户端:
public class TestObserver { public static void main(String[] args) { System.out.println("===========老板自己的行为通知=========="); // 创建一个通知者 Subject subject = new Boss("老板", "出去了"); // 多个观察者 Observer ob1 = new EmployeeNBAObserver("我爱看NBA", subject); Observer ob2 = new EmployeeStockObserver("我爱炒股", subject); // 通知者,添加观察者 subject.attacth(ob1); subject.attacth(ob2); // 发出通知 subject.notifyObserver(); // 不通知炒股的人 subject.detach(ob2); subject.state = "回来了"; subject.notifyObserver(); // 炒股的人还在炒股,被老板发现 System.out.println(ob2 + "被老板发现在炒股"); System.out.println("===========前台小妹通知老板回来=========="); // 创建小妹 subject = new ReceptionGirl("前台小妹", "出去了"); // 多个观察者 Observer ob3 = new EmployeeNBAObserver("我爱看NBA", subject); Observer ob4 = new EmployeeStockObserver("我爱炒股", subject); // 通知者,添加观察者 subject.attacth(ob3); subject.attacth(ob4); // 发出通知 subject.notifyObserver(); subject.state = "回来了"; subject.notifyObserver(); } }控制台输出:
分析:
1.老板和前台小妹都是通知者
2.观察者需要知道老板的状态
3.通知者中使用Vector容器不使用List,是因为多线程操作时,Vector是安全地,而List是不安全的。
观察者模式优点
观察者与被观察者之间属于轻度的关联关系,并且是抽象耦合的,对于两者比较容易扩展。观察者模式是一种常用的触发机制,形成一条触发链,依次对各个观察者的方法进行处理。但是由于链式触发,当观察者比较多的时候,性能问题很难解决。并且链式结构容易出现循环引用错误,造成系统假死。
使用场景
当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象有待给边,应该考虑使用观察者模式。观察者模式所做的工作就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。
另外,Java语言中,有接口Observer和它的实现类Observable,对观察者角色进行了实现。
相关文章推荐
- Android微信支付遇到的坑
- 【数据结构与算法】自己动手实现图的BFS和DFS(附完整源码)
- 解决常见的masksToBounds离屏渲染带来的性能损耗
- Android Log日志规则打印
- IEEE1888-物联网领域的绿色节能标准(三)
- Android中ListView的addFooterView不显示的问题
- jquery mobile实例
- Eclipse注释模板设置详解
- mac idea优化
- 阿里数据研发工程师实习生面试经历
- [经典排序算法][集锦]
- Actionbar标题栏中的Spinner下拉菜单效果受theme影响
- 建立更可靠的开发方法——基于官方API文档的学习尝试之异常处理
- eclipse中tomcat启动时jar not loaded,\WEB-INF\classes\下无class文件
- qgis加载geoserver wms图层
- 安卓多级列表简单实现
- 协同过滤介绍和简单推荐系统的实现
- C++中一个常用的句型(两个for(;;)语句连用的重要性)
- WCF通过SVCUtil.exe生成客户端代理类和配置文件(转)
- 面向 Web 开发者的 Sublime Text 插件