`

Java 设计模式——观察者模式(转)

阅读更多

一、概述

Java的设计模式很多,观察者模式被称为是模式中的皇后,而且Java jdk也对它做了实现,可见该设计模式的重要位置。在图形化设计的软件中,为了实现视图和事件处理的分离,大多都采用了Observer模式,比如 Java的Swing,Flex的ActionScript等。在现实的应用系统中也有好多应用,比如像当当网、京东商城一类的电子商务网站,如果你对某 件商品比较关注,可以放到收藏架,那么当该商品降价时,系统给您发送手机短信或邮件。这就是观察者模式的一个典型应用,商品是被观察者,有的叫主体;关注 该商品的客户就是观察者。下面的一个事例将模拟这个应用。  



GoF说道:Observer模式的意图是“定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。从这段话里我们可以得到两个信息,如下:



1, 观察者(具体执行操作的对象,有多个)

2, 被观察者(顾名思义是被观察的对象,如果该对象发生某些变化则通知观察者执行对应的操)



二、jdk中观察者模式解析



在java的util包中实现了该设计模式的框架,大部分应用都可以直接用它,当然了你也可以自己实现它,实际上就是一个被观察者的抽象类和一个观察者接口。我们先看一下jdk是如何实现的。被观察者的抽象类java.util.Observable



package java.util;

public class Observable {

private boolean changed = false;

private Vector obs;



//创建被观察者时就创建一个它持有的观察者列表,注意,这个列表是需要同步的。

public Observable() {

obs = new Vector();

}

/**

* 添加观察者到观察者列表中去

*/
public synchronized void addObserver(Observer o) {

if (o == null)

throw new NullPointerException();

if (!obs.contains(o)) {

obs.addElement(o);

}

}

/**

* 删除一个观察者

*/
public synchronized void deleteObserver(Observer o) {

obs.removeElement(o);

}

public void notifyObservers() {

notifyObservers(null);

}

/**
* 通知操作,即被观察者发生变化,通知对应的观察者进行事先设定的操作,这个方法接受一个参数,这个参数一直传到观察者里,以供观察者使用
*/

public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}

public synchronized void deleteObservers() {
obs.removeAllElements();
}

protected synchronized void setChanged() {
changed = true;
}

protected synchronized void clearChanged() {
changed = false;
}


public synchronized boolean hasChanged() {
return changed;
}

public synchronized int countObservers() {
return obs.size();
}
}

当我们自己的被观察者继承这个Observable类是,我们就自动的获取到被观察者的一切条件了。很方便是不是,这也是为什么sun要把Observable放到java.util包中的原因,就是为了方便开发者。

下面我们再看一下观察者的接口java.util.Observer
package java.util;
public interface Observer {

void update(Observable o, Object arg);

}

接口中就只有一个方法,update,方法中有两个参数,Observable和一个object,第一个参数就是被观察的对象,而第二个参数就 得看业务需求了,需要什么就传进去什么。我们自己的观察者类必须实现这个方法,这样在被观察者调用notifyObservers操作时被观察者所持有的 所有观察者都会执行update操作了.



三、观察者模式应用



下面是一个book对象,它是一个被观察者,所以要继承Observable。

import java.util.Observable;

public class Book extends Observable {



private String name = "";

private double price = 0.0;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}



public double getPrice() {

return price;

}

public void setPrice(double price) {

this.price = price;

}

//当书的价格修改时调用该方法

public void modifyPrice(Book b) {

//调用父类的方法,改变被观察者的状态

setChanged();

//通知客户该书已降价

notifyObservers(b);

}



}



下面是观察者对象,表示顾客的电子邮件,它实现了Observer接口。

import java.util.Observable;

import java.util.Observer;

public class BuyerEmail implements Observer {



private String buyerId = "";

private String email = "";



public String getBuyerId() {

return buyerId;

}

public void setBuyerId(String buyerId) {

this.buyerId = buyerId;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

//该方法会被“被观察者的父类”既Observable调用

public void update(Observable o, Object arg) {

//这里做具体发电子邮件的操作

Book b = (Book)arg;

System.out.println("给顾客的发电子邮件:"+b.getName()+"降价了,目前价格为:"+b.getPrice());

}

}



下面是另一个观察者对象,表示顾客的手机,同样需要继承Observer接口

import java.util.Observable;

import java.util.Observer;

public class BuyerMobileMessage implements Observer {



private String buyerId = "";

private String mobileNo = "";



public String getBuyerId() {

return buyerId;

}

public void setBuyerId(String buyerId) {

this.buyerId = buyerId;

}

public String getMobileNo() {

return mobileNo;

}

public void setMobileNo(String mobileNo) {

this.mobileNo = mobileNo;

}

public void update(Observable o, Object arg) {

// TODO Auto-generated method stub

Book b = (Book)arg;

System.out.println("给顾客的发手机短信:"+b.getName()+"降价了,目前价格为:"+b.getPrice());

}

}



下面是调用类:



public class MainApp {



public static void main(String args[])

{

Book b1 = new Book();

b1.setName("<<Java设计模式>>");

b1.setPrice(45.00);//假设原价是60,现在是降价促销



//下面的观察者在实际的应用中可以从数据库或文件中读取

BuyerMobileMessage bm = new BuyerMobileMessage();

bm.setBuyerId("001");

bm.setMobileNo("13810500085");



BuyerEmail be = new BuyerEmail();

be.setBuyerId("001");

be.setEmail("dobodo@163.com");



//增加观察者,在实际应用中就是那些人对该书做了关注

b1.addObserver(bm);

b1.addObserver(be);



b1.modifyPrice(b1);

}

}



输出:

给顾客的发电子邮件:<<Java设计模式>>降价了,目前价格为:45.0

给顾客的发手机短信:<<Java设计模式>>降价了,目前价格为:45.0

===================================================================================

总结:

 Observable 被观察者 (类)
  方法:添加观察者,删除观察者,通知观察者更新
  Observable中使用Vector而不使用ArrayList 因为需要多线程同步
  Observable有一个标志位  观察者更新的时候需要判断此标志位来做相应的事情 。
  Observer   观察者(接口)方法:void update(Observable o, Object arg);
   使用接口的原因我们应该理解为给自己的类添加一种Observer功能而不是吧自己的类当成观察者抽象类。

 

 

       观察者模式:就是运用了java的继承和接口,在被观察者的抽象类里设置一个状态标志,通过该标志判断是否通知观察者对象。在学习该模式的同时,我们更应该学习java的继承和接口的灵活应用,其实所有的设计模式都是继承、接口、多态的灵活应用。

 

 

分享到:
评论

相关推荐

    Java设计模式——观察者模式

    Java设计模式——观察者模式的两种情况。

    浅析Java设计模式【1】——观察者

    浅析Java设计模式【1】——观察者!

    Java设计模式 版本2

    对象间的联动——观察者模式,处理对象的多种状态及其相互转换——状态模式,算法的封装与切换——策略模式,模板方法模式深度解析,操作复杂对象结构——访问者模式,设计模式与足球,多人联机射击游戏中的设计模式...

    KWIC 程序示例 事件风格 观察者模式

    KWIC 程序示例 事件风格 观察者模式的程序代码,使用的是Java语言。

    java设计模式

    22.4.1 Java世界中的观察者模式 22.4.2 项目中真实观察者模式 22.4.3 订阅发布模型 22.5 最佳实践 第23章 门面模式 23.1 我要投递信件 23.2 门面模式的定义 23.3 门面模式的应用 23.3.1 门面模式的优点 23.3.2 门面...

    java和设计模式ppt教程

    java和设计模式ppt包含工厂模式、建造模式、原始模型模式、单例模式、结构模式、适配器、桥梁模式、合成模式、装饰模式、门面模式、享元模式、代理模式、行为模式、解释器模式、迭代子模式、调停者模式、备忘录模式...

    深入浅出设计模式(中文版电子版)

    5.7ObserverPattern(观察者模式) 236 5.7.1定义 236 5.7.2现实例子——拉登现身了 238 5.7.3C#实例——猫和老鼠 238 5.7.4C#实例——股票变化 241 5.7.5Java实例——监控系统 245 5.7.6优势和缺陷 248 ...

    深入浅出设计模式(中文版)

    5.7ObserverPattern(观察者模式) 236 5.7.1定义 236 5.7.2现实例子——拉登现身了 238 5.7.3C#实例——猫和老鼠 238 5.7.4C#实例——股票变化 241 5.7.5Java实例——监控系统 245 5.7.6优势和缺陷 248 ...

    design-pattern-java.pdf

    撤销功能的实现——备忘录模式(三) 撤销功能的实现——备忘录模式(四) 撤销功能的实现——备忘录模式(五) 观察者模式-Observer Pattern 对象间的联动——观察者模式(一) 对象间的联动——观察者模式(二) ...

    设计模式——开发常用的设计模式梳理

    本文来自51cto,文章主要介绍了策略模式、观察者模式、装饰模式、单例模式以及饿汉模式等的相关内容。泛化=实现&gt;组合&gt;聚合&gt;关联&gt;依赖一个人(Person)可以买车(car)和房子(House),那么就可以称:Person类依赖于Car类...

    设计模式精解 译者:熊节 程序员必看书籍之一 part2

    设计模式精解(Design Patterns Explained) ...如何实现关键模式——Strategy(策略)、Observer(观察者)、Bridge(桥接)、Decorator(装饰)等等。 共同点/变化点分析、设计模式以及它们如何帮助理解抽象类。

    java高手真经 (UML建模+设计模式+面向服务架构) 卷6

    pattern/src/behavior/strategy //13.1策略模式 pattern/src/behavior/templatemethod //13.2模板方法模式 pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 ...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷8

    pattern/src/behavior/strategy //13.1策略模式 pattern/src/behavior/templatemethod //13.2模板方法模式 pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 ...

    软件设计模式大作业

    java设计模式期末大作业,运用了6种模式,包括简单工厂模式、工厂方法模式、单例模式、门面模式、策略模式、观察者模式,文档包括系统流程,系统类图,各个模式的子类图,源代码,实验截图。绝对完整.

    java高手真经 (UML建模+设计模式+面向服务架构) 卷3

    pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 pattern/src/behavior/chainofresponsibility//13.5责任链模式 pattern/src/behavior/command //13.6命令模式 ...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷1

    pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 pattern/src/behavior/chainofresponsibility//13.5责任链模式 pattern/src/behavior/command //13.6命令模式 ...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷9

    pattern/src/behavior/strategy //13.1策略模式 pattern/src/behavior/templatemethod //13.2模板方法模式 pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 ...

    设计模式Demo

    行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 其实还有两类:并发型模式和线程池模式。 二、设计...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷10

    pattern/src/behavior/strategy //13.1策略模式 pattern/src/behavior/templatemethod //13.2模板方法模式 pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 ...

Global site tag (gtag.js) - Google Analytics