观察者模式
2016-07-22 17:00
134 查看
观察者模式是非常实用的一种设计模式。他可以降低对象之间的耦合度,实现松耦合。
比如我们编程中,如果你的一个对象获得了一个数据,他要将这个数据通知很多别的对象,让那些对象实现数据的更新。最简单的方法如下:
但是这样你会发现,代码明显重复。针对具体实现编程,这样会使我们日和增加或删除某个要通知的对象必须要修改程序。比如你不想通知t2了,你要对源程序进行代码的修改。
解决的办法是 我们可以把拥有公共update的被通知对象抽象出来。然后让该通知者在每次有数据更新的时候实现数据通知。这就引入了观察者模式。
所以被通知的对象都是观察者,负责通知的为主题对象(各种主题通知如邮件主题、新闻等主题都可)。
我就采用比较易懂的语言说下吧。
比如一群码农想在公司附近找房子住,但是呢码农们都比较忙,没有时间去找房子。于是他们找到了房产中介,让中介帮他们找房子,中介有房源消息的时候再通知码农们。
这个事例之中的 码农就是观察者,房产中介就是主题对象。房产中介有新的消息要对观察者(码农们)进行实时的通知。观察者们(码农们)没收到通知的时候就正常的干自己的工作,当收到消息的时候可以采取适当的行动。下面来进行代码的实现。
首先是码农们都是一类人,所以可以将码农们抽象出来,他们除了干各自的工作外,他们都有些公共的行为如查找房子看房子。
先写码农的祖先
public interface Subject {
public void notifyObserver();//通知码农们
public void registerObserver(Observer obs);//注册观察者
public void removeObserver(Observer obs);//删除该观察者
}下面是房产中介了,房产中介不唯一,每个观察者可以关注多个房产中介。但是所有房产中介都有同样的一些功能,都实现Subject接口
public class Agency1 implements Subject {
private ArrayList<Observer> obsList;//用集合存储观察者集,实现一对多的关系
private String information;
public Agency1() {
// TODO Auto-generated constructor stub
obsList=new ArrayList<Observer>();
}
@Override
public void notifyObserver() {
// TODO Auto-generated method stub
for(Observer ob:obsList)
ob.update(this.information);
}
@Override
public void registerObserver(Observer obs) {
// TODO Auto-generated method stub
obsList.add(obs);
}
@Override
public void removeObserver(Observer obs) {
// TODO Auto-generated method stub
int i=obsList.indexOf(obs);
if(i>=0)
obsList.remove(i);
}
public void measurementsChanged(){
notifyObserver();
}
public void setInfor(String info){//得到新消息,设置新消息并通知所有观察者
this.information=info;
measurementsChanged();
}
}coder1 获得消息:中关村有好房子 内心思想:可以观望下
coder2 获得消息:中关村有好房子 内心思想:这不是coder2我需要的房子
coder3 获得消息:中关村有好房子 内心思想:我要抓紧必须抢占
运行结果如上。
内心思想为每个码农的思想,其实就是每个码农获得消息后该采取的后续行动,各自不同。
这样观察者模式就实现了。如果新增码农找房子,中介只需要将其注册如list中,如果某个码农不想找了那么中介直接remove删除就好,而不需要对代码就行修改。实现了松耦合。
主题和观察者之间定义了一对多的关系。观察者依赖于主题,只要主题状态一有变更,观察者便会接收到通知。
关于观察者,主题只知道观察者实现了某个接口(Observer接口)。不需要知道具体类是谁,做了什么,什么细节
任何时候可以增加新的观察者。同时也可以删除观察者。
有新类型的观察者出现,主题的代码不需要更改。改变主题或者观察者任何一方不会影响另一方,因为二者是松耦合的,只要他们之间的接口仍被遵守,就能自由改变他们。
观察者模式设计原则为:为了交互对象之间的松耦合设计而努力。对象之间的互相依赖降到了最低
其实在java源码类中有很多也是观察者模式思想。
如java swing中 JButton类。该类有添加监听器(实际就是添加观察者)。当JButton改变时,监听器获得消息进行相应行动。
同时java也有自己的Observer为java.util.Observer类。但是该类有些许问题,该类为抽象类,这样我们的观察者必须继承该类。这在只支持但继承的java语言会带来很大的劣势,让观察者无法再继承别的父类,不可取。其实我们可以写Observer不难。
观察者模式现实了主题1对观察者多的一对多的关系。主题不知道观察者的细节,只知道观察者实现了观察者接口。
总结下:观察者模式能降低对象间的关联程度,实现松耦合。符合”开闭原则”,但是呢这种广播通知必定会耗费大量时间。如果观察者与主题之间是循环依赖的话,这种广播触发会导致系统的崩溃。
以上是个人的一点浅见。不喜勿喷。
比如我们编程中,如果你的一个对象获得了一个数据,他要将这个数据通知很多别的对象,让那些对象实现数据的更新。最简单的方法如下:
T1 t1=new T1(); T2 t2=new T2(); T3 t3=new T3(); t2.update(info); t1.update(info); t3.update(info);
但是这样你会发现,代码明显重复。针对具体实现编程,这样会使我们日和增加或删除某个要通知的对象必须要修改程序。比如你不想通知t2了,你要对源程序进行代码的修改。
解决的办法是 我们可以把拥有公共update的被通知对象抽象出来。然后让该通知者在每次有数据更新的时候实现数据通知。这就引入了观察者模式。
所以被通知的对象都是观察者,负责通知的为主题对象(各种主题通知如邮件主题、新闻等主题都可)。
我就采用比较易懂的语言说下吧。
比如一群码农想在公司附近找房子住,但是呢码农们都比较忙,没有时间去找房子。于是他们找到了房产中介,让中介帮他们找房子,中介有房源消息的时候再通知码农们。
这个事例之中的 码农就是观察者,房产中介就是主题对象。房产中介有新的消息要对观察者(码农们)进行实时的通知。观察者们(码农们)没收到通知的时候就正常的干自己的工作,当收到消息的时候可以采取适当的行动。下面来进行代码的实现。
首先是码农们都是一类人,所以可以将码农们抽象出来,他们除了干各自的工作外,他们都有些公共的行为如查找房子看房子。
先写码农的祖先
public interface Observer { public void update(String info); public void seeHouse(String info); }下面是各个码农了,他们都实现了祖先
package ObserveMode; public class Coder1 implements Observer { public Coder1(Subject sub) { // TODO Auto-generated constructor stub sub.registerObserver(this); } @Override public void update(String info) { // TODO Auto-generated method stub display(info); } @Override public void seeHouse(String info) { // TODO Auto-generated method stub System.out.println("coder1 获得消息:"+info+" 内心思想:可以观望下"); } } class Coder2 implements Observer { public Coder2(Subject sub) { // TODO Auto-generated constructor stub sub.registerObserver(this); } @Override public void update(String info) { // TODO Auto-generated method stub display(info); } @Override public void seeHouse(String info) { // TODO Auto-generated method stub System.out.println("coder2 获得消息:"+info+" 内心思想:这不是coder2我需要的房子"); } } class Coder3 implements Observer { public Renter3(Subject sub) { // TODO Auto-generated constructor stub sub.registerObserver(this); } @Override public void update(String info) { // TODO Auto-generated method stub display(info); } @Override public void seeHouse(String info) { // TODO Auto-generated method stub System.out.println("coder3 获得消息:"+info+" 内心思想;我要抓紧必须抢占"); } }下面是主题类抽象,他们都有同样的一些功能。将这些功能抽象为接口
public interface Subject {
public void notifyObserver();//通知码农们
public void registerObserver(Observer obs);//注册观察者
public void removeObserver(Observer obs);//删除该观察者
}下面是房产中介了,房产中介不唯一,每个观察者可以关注多个房产中介。但是所有房产中介都有同样的一些功能,都实现Subject接口
public class Agency1 implements Subject {
private ArrayList<Observer> obsList;//用集合存储观察者集,实现一对多的关系
private String information;
public Agency1() {
// TODO Auto-generated constructor stub
obsList=new ArrayList<Observer>();
}
@Override
public void notifyObserver() {
// TODO Auto-generated method stub
for(Observer ob:obsList)
ob.update(this.information);
}
@Override
public void registerObserver(Observer obs) {
// TODO Auto-generated method stub
obsList.add(obs);
}
@Override
public void removeObserver(Observer obs) {
// TODO Auto-generated method stub
int i=obsList.indexOf(obs);
if(i>=0)
obsList.remove(i);
}
public void measurementsChanged(){
notifyObserver();
}
public void setInfor(String info){//得到新消息,设置新消息并通知所有观察者
this.information=info;
measurementsChanged();
}
}coder1 获得消息:中关村有好房子 内心思想:可以观望下
coder2 获得消息:中关村有好房子 内心思想:这不是coder2我需要的房子
coder3 获得消息:中关村有好房子 内心思想:我要抓紧必须抢占
运行结果如上。
内心思想为每个码农的思想,其实就是每个码农获得消息后该采取的后续行动,各自不同。
这样观察者模式就实现了。如果新增码农找房子,中介只需要将其注册如list中,如果某个码农不想找了那么中介直接remove删除就好,而不需要对代码就行修改。实现了松耦合。
主题和观察者之间定义了一对多的关系。观察者依赖于主题,只要主题状态一有变更,观察者便会接收到通知。
关于观察者,主题只知道观察者实现了某个接口(Observer接口)。不需要知道具体类是谁,做了什么,什么细节
任何时候可以增加新的观察者。同时也可以删除观察者。
有新类型的观察者出现,主题的代码不需要更改。改变主题或者观察者任何一方不会影响另一方,因为二者是松耦合的,只要他们之间的接口仍被遵守,就能自由改变他们。
观察者模式设计原则为:为了交互对象之间的松耦合设计而努力。对象之间的互相依赖降到了最低
其实在java源码类中有很多也是观察者模式思想。
如java swing中 JButton类。该类有添加监听器(实际就是添加观察者)。当JButton改变时,监听器获得消息进行相应行动。
同时java也有自己的Observer为java.util.Observer类。但是该类有些许问题,该类为抽象类,这样我们的观察者必须继承该类。这在只支持但继承的java语言会带来很大的劣势,让观察者无法再继承别的父类,不可取。其实我们可以写Observer不难。
观察者模式现实了主题1对观察者多的一对多的关系。主题不知道观察者的细节,只知道观察者实现了观察者接口。
总结下:观察者模式能降低对象间的关联程度,实现松耦合。符合”开闭原则”,但是呢这种广播通知必定会耗费大量时间。如果观察者与主题之间是循环依赖的话,这种广播触发会导致系统的崩溃。
以上是个人的一点浅见。不喜勿喷。
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- C#中观察者模式的3种实现方式
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C# 设计模式系列教程-建造者模式
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用