设计模式-观察者模式(Observer Pattern)

本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/

观察者模式简述

观察者模式的使用非常广泛,常用于建立起一种多对一的关系,该模式一定会包含两个角色,观察者和被观察的对象,当被观察的对象发生变化的时候观察者会接受到相应的通知。

策略模式的定义与基本结构

定义:定义一个一对多的依赖关系,当被多个对象依赖的那个对象发生改变的时候,所有依赖它的对象都会得到相应的通知并进行状态的更新。

让我们来看一张来自《Head First》的结构图。

Subject:被观察对象的接口,只要实现了这个接口,任何类都可以成为被观察的对象,这种面向接口的编程方式让类之间的耦合度降低。

Observer:观察者对象的接口,只要实现了这个接口,任何类都可以成为被观察的对象,这种面向接口的编程方式让类之间的耦合度降低。

ConcreteSubject:实现了Subject接口的具体实例。

ConcreteObserver:实现了Observer接口的具体实例。

注:一对多指的是一个Subject可以被很多observer观察。

一个简单的实例(java)

从观察者更新信息的方式上,可以将观察者模式的实现分成两类,一类是每次Subject更新了信息,Observer都会收到更新的信息(被称为push方式),另一类是每次Subject更新的时候,只通知Observer信息被更新了,但是需要Observer在需要的时候自己来取新的信息(被称为pull方式)。

我们只给出push方式完整的代码,然后文字叙述pull与push实现的区别,感兴趣的朋友可以自己试着实现pull版本。

让我们来考虑这样一个例子,只要我们定了一份新的杂志,每当这份杂志有新的版本的时候,在push方式下,这本杂志就会被送到每一个订阅者的家里,这里发行商就是ConcreteSubject类,顾客是ConcreteObserver类,实现如下。

Subject接口

1 public interface Subject {
2     void addObserver(Observer o);
3     void deleteObserver(Observer o);
4     void notifyObserver();
5 }

Observer接口

1 public interface Observer {
2     void update(String magazine);
3 }

Publisher类,继承了Subject接口

 1 public class Publisher implements Subject {
 2     private ArrayList<Observer> customer;
 3     private String magazine;
 4     public Publisher(){
 5         customer=new ArrayList<Observer>();
 6         magazine="";
 7     }
 8     @Override
 9     public void addObserver(Observer o) {
10         customer.add(o);
11         System.out.println("新顾客加入");
12     }
13
14     @Override
15     public void deleteObserver(Observer o) {
16         customer.remove(o);
17         System.out.println("老顾客退出");
18     }
19     @Override
20     public void notifyObserver() {
21         for(Observer o:customer){
22             o.update(magazine);
23         }
24     }
25     public void publishNewMagazine(String magazine){
26         this.magazine=magazine;
27         notifyObserver();
28     }
29 }

Customer类,继承了Observer接口

 1 public class Customer implements Observer {
 2     String name;
 3     public Customer(String name){
 4         this.name=name;
 5     }
 6     @Override
 7     public void update(String magazine) {
 8         System.out.println(name+" 拿到了新的杂志 "+magazine)    ;
 9     }
10 }

测试程序如下

 1 public class Test {
 2     public static void main(String[] args) {
 3         Publisher publisher=new Publisher();
 4         Customer customer1=new Customer("叶良辰");
 5         Customer customer2=new Customer("龙傲天");
 6         publisher.addObserver(customer1);
 7         publisher.addObserver(customer2);
 8         publisher.publishNewMagazine("装B指南");
 9         publisher.deleteObserver(customer1);
10         publisher.publishNewMagazine("上天秘籍");
11     }
12 }

输出如下

pull与push主要的区别

1,pull式需要Observer自己去取数据,所以Subject要提供相应的get方法

2,pull式虽然不用主动push数据,但是仍然要在每次更新时告知Observer数据已经更新,所以每一个Observer需要设立一个flag表示自己数据的新旧。

3,object需要判断哪些Observer有权限来取得自己的数据。

(pull方式在那种只有最新信息有价值且Subject更新太快而不适合用push的情况下使用比较好,比如手机上接受天气预报信息之类的)

Java的built-in Observer Pattern

因为观察者模式实在是太常用了,以至于java给我提供了相应的工具直接构建Observer模式,java提供了一个Observable类(作用相当于我们刚刚写的Object,但是这个是类不是接口),和Observer接口,我们只要继承这些类和接口就能直接应用观察者模式了

它们的位置

import java.util.Observable;
import java.util.Observer;

Observer类里有以下成员方法

addObserver(Observer o);//添加observer
clearChanged();//重置更新标志,hasChanged()的返回值将为false
countObservers();//返回observer的数量
deleteObserver(Observer o);//删除一个特定的observer
deleteObservers();//删除所有observer
hasChanged();//测试object的内容距上一次通知后有没有更新
notifyObservers();//如果object内容有更新,调用这个方法会通知所有observer,之后会调用clearChange()方法,这个方法是为pull式实现准备的。
notifyObservers(Object arg);//如果object内容有更新,调用这个方法会将参数中arg的更新推送给所有observer,之后会调用clearChange()方法,这个方法是为push式实现准备的
setChanged();//标明object已经更新

Observer接口里面只有一个update方法,声明如下

public void update(Observable o, Object arg);

第一个参数是被观察的对象,第二个是任何我们想更新给observer的对象,这个对象来自notifyObservers的参数,如果缺失这个参数,表示我们的observer需要自己来拿数据(即pull式实现),如果有这个对象,则属于push式实现。

运用这个java提供的观察者模式的实现我们只需要做两件事。

1,决定使用pull式实现还是push式实现。

2,根据我们的决定实现update方法,如果我们用pull式实现,我们最好在Subject类里提供相应的get方法。

这里给出一个示例,还是上面的例子,仍然是push式,这次我们不用写object与observer接口了。

Customer类

 1 public class Customer implements Observer {
 2     String name;
 3     boolean newManagzine=false;
 4     public Customer(String name){
 5         this.name=name;
 6     }
 7     @Override
 8     public void update(Observable o, Object arg) {
 9             System.out.println(name+" 拿到了新的杂志 "+arg);
10     }
11 }

Publisher类

 1 import java.util.Observable;
 2 public class Publisher extends Observable {
 3     private String magazine;
 4     public Publisher(){
 5         super();
 6         magazine="";
 7     }
 8     public void publishNewMagazine(String magazine){
 9         setChanged();
10         this.magazine=magazine;
11         notifyObservers(magazine);
12     }
13 }

test代码完全不用改,输出如下

java给的观察者模式的实现方法其实还有有蛮多的局限性的,比如observable是个类而不是接口,而java是不支持多继承的,所以有了局限性,所以大多数情况下,我们还是自己实现会比较方便。

观察者模式到此结束?(^∇^*)

参考资料:

1,《Head First 设计模式》

2,在线java API http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4

时间: 2024-10-09 06:26:38

设计模式-观察者模式(Observer Pattern)的相关文章

设计模式 - 观察者模式(Observer Pattern) 详解

观察者模式(Observer Pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权所有, 禁止转载, 如有转载, 请站内联系. 观察者模式(Observer Pattern): 定义了对象之间的一对多的依赖, 这样一来, 当一个对象改变状态时, 它的所有依赖者都会收到通知并自动更新. 使用方法: 1. 首先新建主题(subject)接口, 负责注册(register)\删除(remove

设计模式 - 观察者模式(Observer Pattern) Java内置 使用方法

观察者模式(Observer Pattern) Java内置 使用方法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 观察者模式(observer pattern)详解, 参见: http://blog.csdn.net/caroline_wendy/article/details/26583157 Java内置的观察者模式, 是通过继承父类, 实现观察者模式的几个主要函数: Observerable(可被观

设计模式 - 观察者模式(Observer Pattern) 详细说明

观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部, 禁止转载, 如有转载, 请站内联系. 观察者模式(Observer Pattern): 定义了对象之间的一对多的依赖, 这样一来, 当一个对象改变状态时, 它的全部依赖者都会收到通知并自己主动更新. 用法: 1. 首先新建主题(subject)接口, 负责注冊(register)\删除(remo

C#设计模式——观察者模式(Observer Pattern)

一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依赖,以松耦合的方式实现这一目标.二.观察者模式观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新.其结构图如下: Subject知道它的所有观察者并提供了观察者注册和删除订阅的接口.Observer为那些在目标发生改变时需获得通知的对象定义

23种设计模式--观察者模式-Observer Pattern

一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项目我们经常会用这些例子,这样避免了我们使用接口等那些依赖,比如电商项目中得降价通知,然后在来个生活中具体一点的比如公交车的例子,每一站都会对乘客进行提醒等等,我列举的这2个例子在我GITHUb上都有体现:下面用降价通知的Demo给大家具体来说一下,具体的代码还需要大家去下载观看: 二.观察者模式De

Java设计模式之观察者模式(Observer Pattern)

Observer Pattern 是一种常用的设计模式,它是一种事件监听模型.该模式有两个角色,一个是Subject, 另一个是Observer.Subject 保存有多个Observer的引用,一旦特定的事件发生,Subject会通知它所有的Observer,Observer得到该通知后执行相关程序逻辑.其中,Observer只有先向Subject注册后才能被Subject知晓.这就像订报纸,只有我们向出版社提出订报的申请,出版社才会把我们列入订阅者名单,然后每当新报纸印好时,出版社会通知订阅

说说设计模式~观察者模式(Observer)

观察者模式,也叫发布/订阅模式(publish/subscribe),监视器模式等.在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现.. 何时能用到它? 此种模式通常被用来实现事件处理系统,例如,当一个数据仓储操作中,它的添加功能可能会有一个功能,当添加被触发时,所以订阅了这个添加事件需求的代码 块,都会被触发执行,在这个过程中,数据仓储的添加操作就是被观察者,而所以的订阅者就是它的观察者,发被观察者在某种情况

jQuery中的观察者模式(Observer Pattern)

在jQuery中,on方法可以为元素绑定事件,trigger方法可以手动触发事件,围绕这2个方法,我们来体验jQuery中的观察者模式(Observer Pattern). ■ on方法绑定内置事件,自然触发 比如,我们给页面的body元素绑定一个click事件,这样写. <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title&

设计模式之二:观察者模式(Observer Pattern)

先看下观察者模式的定义: The Observer Pattern defines a one-to-many denpendency between objects so that when one object changes state, all of its dependents are notified and updated automatically.:观察者模式定义了对象间一对多依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新. 观察者模式又叫发布-

【设计模式】观察者模式 Observer Pattern

定义:观察者模式定义了对象之间的一对多依赖.当“主题”(Object)状态改变事,所有依赖它的“观察者”(Observer)都会受到通知并自动更新.主题支持观察者订阅和退订. 观察者模式提供了一种对象设计,让主题和观察者之间松耦合.改变主题或观察者一方不会影响另一方.因为两者是松耦合的. 参考: 设计模式学习笔记--Observer Pattern观察者模式