一、概述
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设计模式【1】——观察者!
对象间的联动——观察者模式,处理对象的多种状态及其相互转换——状态模式,算法的封装与切换——策略模式,模板方法模式深度解析,操作复杂对象结构——访问者模式,设计模式与足球,多人联机射击游戏中的设计模式...
KWIC 程序示例 事件风格 观察者模式的程序代码,使用的是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包含工厂模式、建造模式、原始模型模式、单例模式、结构模式、适配器、桥梁模式、合成模式、装饰模式、门面模式、享元模式、代理模式、行为模式、解释器模式、迭代子模式、调停者模式、备忘录模式...
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 ...
撤销功能的实现——备忘录模式(三) 撤销功能的实现——备忘录模式(四) 撤销功能的实现——备忘录模式(五) 观察者模式-Observer Pattern 对象间的联动——观察者模式(一) 对象间的联动——观察者模式(二) ...
本文来自51cto,文章主要介绍了策略模式、观察者模式、装饰模式、单例模式以及饿汉模式等的相关内容。泛化=实现>组合>聚合>关联>依赖一个人(Person)可以买车(car)和房子(House),那么就可以称:Person类依赖于Car类...
设计模式精解(Design Patterns Explained) ...如何实现关键模式——Strategy(策略)、Observer(观察者)、Bridge(桥接)、Decorator(装饰)等等。 共同点/变化点分析、设计模式以及它们如何帮助理解抽象类。
pattern/src/behavior/strategy //13.1策略模式 pattern/src/behavior/templatemethod //13.2模板方法模式 pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 ...
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种模式,包括简单工厂模式、工厂方法模式、单例模式、门面模式、策略模式、观察者模式,文档包括系统流程,系统类图,各个模式的子类图,源代码,实验截图。绝对完整.
pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 pattern/src/behavior/chainofresponsibility//13.5责任链模式 pattern/src/behavior/command //13.6命令模式 ...
pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 pattern/src/behavior/chainofresponsibility//13.5责任链模式 pattern/src/behavior/command //13.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迭代子模式 ...
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 其实还有两类:并发型模式和线程池模式。 二、设计...
pattern/src/behavior/strategy //13.1策略模式 pattern/src/behavior/templatemethod //13.2模板方法模式 pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 ...