`

观察者模式

 
阅读更多
观察者(Observer)模式:是对象的行为模式,又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听(Source/Listener)模式或者从属(Dependents)模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
观察者模式类的结构:
观察者模式角色如下:
抽象主题(Subject)角色:抽象主题角色提供维护一个观察者对象聚集的操作方法,对聚集的增加、删除等。
具体主题(ConcreteSubject)角色:将有关状态存入具体的观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色负责实现抽象主题中聚集的管理方法。
抽象观察者(Observer)角色:为具体观察者提供一个更新接口。
具体观察者(ConcreteObserver)角色:存储与主题相关的自洽状态,实现抽象观察者提供的更新接口。
 
仔细观察上面的类图,发现具体主题角色和抽象观察者之间的连线,是因为具体主题角色维护了一个观察者引用的聚集,如果有多个具体主题角色,意味着每个具体角色都要维护一个观察者的聚集,那么能不能将聚集提升到抽象主题里面呢?这个就需要考虑场景,如果多个主题实现在管理上都有很大差异,那么就不能提升到抽象角色中,但是绝大多数情况下,这些聚集管理方法本身就是所有具体主题所共有的,所以大多数情况下都是可以将聚集和聚集的管理都移入到抽象主题中的,因为notifyObserver()方法是依赖于聚集的,所以将notifyObserver()也移入抽象主题中,这样就形成了如下的另一种观察者模式结构:

 我们这里简单用代码描述如下:
Java代码  收藏代码
  1. package observer.desc;  
  2. /** 
  3.  *  
  4.  *作者:alaric 
  5.  *时间:2013-8-13下午8:05:08 
  6.  *描述:抽象观察者 
  7.  */  
  8. public interface Observer {  
  9.       
  10.     public void update();  
  11.       
  12. }  
 
Java代码  收藏代码
  1. package observer.desc;  
  2. /** 
  3.  *  
  4.  *作者:alaric 
  5.  *时间:2013-8-13下午8:05:34 
  6.  *描述:具体观察者 
  7.  */  
  8. public class ConcreteObserver implements Observer{  
  9.   
  10.     @Override  
  11.     public void update() {  
  12.         // 写业务逻辑  
  13.     }  
  14.   
  15. }  
 
Java代码  收藏代码
  1. package observer.desc;  
  2. /** 
  3.  *  
  4.  *作者:alaric 
  5.  *时间:2013-8-13下午8:05:55 
  6.  *描述:抽象主题 
  7.  */  
  8. public interface Subject {  
  9.   
  10.     public void attach(Observer observer);  
  11.   
  12.     public void detach(Observer observer);  
  13.   
  14.     void notifyObservers();  
  15. }  
 
Java代码  收藏代码
  1. package observer.desc;  
  2.   
  3. import java.util.Enumeration;  
  4. import java.util.Vector;  
  5. /** 
  6.  *  
  7.  *作者:alaric 
  8.  *时间:2013-8-13下午8:09:21 
  9.  *描述:具体主题类 
  10.  */  
  11. public class ConcreteSubject implements Subject {  
  12.     private Vector<Observer>observersVector = new Vector<Observer>();  
  13.     public void attach(Observer observer) {  
  14.         observersVector.addElement(observer);  
  15.     }  
  16.   
  17.     public void detach(Observer observer) {  
  18.         observersVector.removeElement(observer);  
  19.     }  
  20.   
  21.     public void notifyObservers() {  
  22.         Enumeration<Observer>enumeration = observers();  
  23.         while (enumeration.hasMoreElements()) {  
  24.             ((Observer) enumeration.nextElement()).update();  
  25.         }  
  26.     }  
  27.   
  28.     @SuppressWarnings("unchecked")  
  29.     public Enumeration<Observer> observers() {  
  30.         return ((Vector<Observer>) observersVector.clone()).elements();  
  31.     }  
  32.   
  33. }   
上面代码描述第一种形式,第二种读者可以自己实现,这里不再赘述。
接下来我们看java语言是如何支持观察者模式的,java提供一个被观察者类java.util.Observable和一个观察者接口java.util.Observer。

jdk1.6中API文档如下描述:

public interface Observer

一个可在观察者要得到 observable 对象更改通知时可实现 Observer 接口的类。

从以下版本开始:

JDK1.0

另请参见:

Observable

 

public class Observableextends Object

此类表示模型视图范例中的 observable 对象,或者说“数据”。可将其子类化,表示应用程序想要观察的对象。

一个 observable 对象可以有一个或多个观察者。观察者可以是实现了 Observer 接口的任意对象。一个 observable 实例改变后,调用 Observable 的 notifyObservers 方法的应用程序会通过调用观察者的 update 方法来通知观察者该实例发生了改变。

 

未指定发送通知的顺序。Observable 类中所提供的默认实现将按照其注册的重要性顺序来通知 Observers,但是子类可能改变此顺序,从而使用非固定顺序在单独的线程上发送通知,或者也可能保证其子类遵从其所选择的顺序。

 

注意,此通知机制与线程无关,并且与 Object 类的 wait 和 notify 机制完全独立。 新创建一个 observable 对象时,其观察者集是空的。当且仅当 equals 方法为两个观察者返回 true 时,才认为它们是相同的。

 

从以下版本开始:

JDK1.0

另请参见: 

notifyObservers(), notifyObservers(java.lang.Object), Observer, Observer.update(java.util.Observable, java.lang.Object)

 

举个例子,如果你看过TVB的警匪片,你就知道卧底的工作方式。一般一个警察可能有几个卧底,潜入敌人内部,打探消息,卧底完全靠他的领导的指示干活,领导说几点行动,他必须按照这个时间去执行,如果行动时间改变,他也要立马改变自己配合行动的时间。领导派两个卧底去打入敌人内部,那么领导相当于抽象主题,而督察警官张三这个人派了两个卧底李四和万王五,张三就相当于具体主题,卧底相当于抽象观察者,这两名卧底是李四和王五就是具体观察者,派的这个动作相当于观察者在主题的登记。那么这个类图如下:
利用javaAPI来实现,代码描述如下: 
Java代码  收藏代码
  1. package observer;  
  2.   
  3. import java.util.List;  
  4. import java.util.Observable;  
  5. import java.util.Observer;  
  6. /** 
  7.  *  
  8.  *作者:alaric 
  9.  *时间:2013-8-13下午9:32:40 
  10.  *描述:警察张三 
  11.  */  
  12. public class Police extends Observable {  
  13.   
  14.     private String time ;  
  15.     public Police(List<Observer> list) {  
  16.         super();  
  17.         for (Observer o:list) {  
  18.             addObserver(o);  
  19.         }  
  20.     }  
  21.     public void change(String time){  
  22.         this.time = time;  
  23.         setChanged();  
  24.         notifyObservers(this.time);  
  25.     }  
  26. }  
 
Java代码  收藏代码
  1. package observer;  
  2.   
  3. import java.util.Observable;  
  4. import java.util.Observer;  
  5. /** 
  6.  *  
  7.  *作者:alaric 
  8.  *时间:2013-8-13下午9:32:59 
  9.  *描述:卧底A 
  10.  */  
  11. public class UndercoverA implements Observer {  
  12.   
  13.     private String time;  
  14.     @Override  
  15.     public void update(Observable o, Object arg) {  
  16.         time = (String) arg;  
  17.         System.out.println("卧底A接到消息,行动时间为:"+time);  
  18.     }  
  19.   
  20.   
  21. }  
 
Java代码  收藏代码
  1. package observer;  
  2.   
  3. import java.util.Observable;  
  4. import java.util.Observer;  
  5. /** 
  6.  *  
  7.  *作者:alaric 
  8.  *时间:2013-8-13下午9:33:14 
  9.  *描述:卧底B 
  10.  */  
  11. public class UndercoverB implements Observer {  
  12.     private String time;  
  13.     @Override  
  14.     public void update(Observable o, Object arg) {  
  15.         time = (String) arg;  
  16.         System.out.println("卧底B接到消息,行动时间为:"+time);  
  17.     }  
  18.   
  19.   
  20.   
  21. }  
 
Java代码  收藏代码
  1. package observer;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import java.util.Observer;  
  6. /** 
  7.  *  
  8.  *作者:alaric 
  9.  *时间:2013-8-13下午9:32:26 
  10.  *描述:测试 
  11.  */  
  12. public class Client {  
  13.   
  14.     /** 
  15.      * @param args 
  16.      */  
  17.     public static void main(String[] args) {  
  18.         UndercoverA o1 = new UndercoverA();  
  19.         UndercoverB o2 = new UndercoverB();  
  20.         List<Observer> list = new ArrayList<>();  
  21.         list.add(o1);  
  22.         list.add(o2);  
  23.         Police subject = new Police(list);  
  24.         subject.change("02:25");  
  25.         System.out.println("===========由于消息败露,行动时间提前=========");  
  26.         subject.change("01:05");  
  27.           
  28.     }  
  29.   
  30. }  

 测试运行结果:

卧底B接到消息,行动时间为:02:25

卧底A接到消息,行动时间为:02:25

===========由于消息败露,行动时间提前=========

卧底B接到消息,行动时间为:01:05

卧底A接到消息,行动时间为:01:05

观察者模式的优点是只要订阅/登记了之后,当被观察者改变时,观察者能自动更新。跟JMS一样,消息发布者发出消息时,只要注册过的都会收到消息。
分享到:
评论

相关推荐

    设计模式-观察者模式.ppt

    观察者模式是一种行为设计模式,它允许你定义一个订阅机制,可以在对象事件发生时通知多个“观察”该对象的其他对象。这个模式的核心在于建立一种一对多的关系,当一个对象的状态改变时,所有依赖于它的对象都会得到...

    设计模式实现——观察者模式

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现发布-订阅...

    java 设计模式 观察者模式 简单实例 包括测试test类

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件驱动或者发布...

    Qt设计模式之观察者模式

    本篇文章将深入探讨Qt中的观察者模式(Observer Pattern),这是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式的核心...

    java观察者模式观察者模式

    观察者模式是设计模式中的一种行为模式,它在Java编程中有着广泛的应用。该模式的主要目的是定义对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式也被...

    设计模式-观察者模式(讲解及其实现代码)

    观察者模式,也被称为发布-订阅模式,是软件设计中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式在分布式系统、事件驱动...

    Java内置观察者模式

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它允许一个对象,当其状态发生改变时,能够自动通知所有依赖它的其他对象。在Java中,这种模式已经被内置到语言核心,使得开发者可以轻松地实现事件驱动...

    设计模式--观察者模式java例子

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    观察者模式模版和例子

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式常用于实现事件驱动的系统或者...

    设计模式之观察者模式Java实现

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    运用MVC模式及观察者模式的java小程序

    在这个名为“运用MVC模式及观察者模式的java小程序”的项目中,我们重点探讨了两种经典的设计模式:Model-View-Controller(MVC)模式和Observer(观察者)模式。这两种模式在JavaWeb开发中扮演着至关重要的角色。 ...

    iOS 设计模式 观察者模式

    观察者模式,也被称为发布-订阅(Publish-Subscribe)模式,是软件设计中的一种行为模式。在iOS开发中,它是一种让多个对象监听或订阅某一个主题对象的状态变化,并在状态变化时自动收到通知的方式。这种模式使得...

    56丨观察者模式(上):详解各种应用场景下观察者模式的不同实现方式1

    观察者模式详解 观察者模式(Observer Design Pattern)是行为型设计模式的一种,主要解决的是“类或对象之间的交互”问题。它定义了一个一对多的依赖关系,当一个对象的状态改变时,所有依赖的对象都会自动收到...

    观察者模式编写的股票分析程序

    观察者模式(Observer Pattern)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在这个"股票分析程序"中,我们很显然看到它利用了这种模式来实时更新股票...

    设计模式之观察者模式

    观察者模式是面向对象设计中的一种经典模式,它在软件工程中扮演着重要的角色,用于实现对象间的松耦合。这种模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并...

    观察者模式源码

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式常用于事件驱动的系统或者实时...

    观察者模式代码

    观察者模式是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在Java或其他面向对象语言中,这种模式通常用于实现事件处理或发布/订阅系统。在给定的“观察者...

    观察者模式练习

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    Unity3D设计模式之观察者模式

    ### Unity3D设计模式之观察者模式 #### 观察者模式概述 观察者模式(Observer Pattern)是一种软件设计模式,属于行为型模式之一。它定义了对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它...

    观察者模式的一个应用

    ### 观察者模式概述与应用 #### 一、观察者模式定义 观察者模式是一种常用的软件设计模式,主要用于处理对象间的依赖关系。在这种模式下,一个对象(称为“主题”或“被观察者”)负责维护一组依赖于它的对象...

Global site tag (gtag.js) - Google Analytics