当前位置:
文档之家› JAVA观察者模式详细介绍及应用
JAVA观察者模式详细介绍及应用
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 BuyerEmail implements Observer {
private String buyerId = ""; private String email = "";
BuyerEmail be = new BuyerEmail(); be.setBuyerId("001"); be.setEmail("dobodo@");
//增加观察者,在实际应用中就是那些人对该书做了关注 b1.addObserver(bm); b1.addObserver(be);
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) {
public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } //当书的价格修改时调用该方法 public void modifyPrice(Book b) { //调用父类的方法,改变被观察者的状态 setChanged(); //通知客户该书已降价 notifyObservers(b); }
下面我们再看一下观察者的接口 java.util.Observer
package java.util; public interface Observer {
void upபைடு நூலகம்ate(Observable o, Object arg); }
接口中就只有一个方法,update,方法中有两个参数,Observable 和一个 object, 第一个参数就是被观察的对象,而第二个参数就得看业务需求了,需要什么就传进去什 么。我们自己的观察者类必须实现这个方法,这样在被观察者调用 notifyObservers 操 作时被观察者所持有的所有观察者都会执行 update 操作了.
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 Observable() { obs = new Vector(); } /** * 添加观察者到观察者列表中去 */ public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } /** * 删除一个观察者 */
一、 概述
Java 的设计模式很多,观察者模式被称为是模式中的皇后,而且 Java jdk 也对它 做了实现,可见该设计模式的重要位置。在图形化设计的软件中,为了实现视图和事件 处理的分离,大多都采用了 Observer 模式,比如 Java 的 Swing,Flex 的 ActionScript 等。在现实的应用系统中也有好多应用,比如像当当网、京东商城一类的电子商务网站, 如果你对某件商品比较关注,可以放到收藏架,那么当该商品降价时,系统给您发送手 机短信或邮件。这就是观察者模式的一个典型应用,商品是被观察者,有的叫主体;关 注该商品的客户就是观察者。下面的一个事例将模拟这个应用。
b1.modifyPrice(b1); } }
输出: 给顾客的发电子邮件:<<Java 设计模式>>降价了,目前价格为:45.0 给顾客的发手机短信:<<Java 设计模式>>降价了,目前价格为:45.0
不知道上面的例子你看懂了没有,观察者模式实际上没什么高深的东西,就是运用 了 java 的继承和接口,在被观察者的抽象类里设置一个状态标志,通过该标志判断是 否通知观察者对象。在学习该模式的同时,我们更应该学习 java 的继承和接口的灵活 应用,其实所有的设计模式都是继承、接口、多态的灵活应用。
GoF 说道:Observer 模式的意图是“定义对象间的一种一对多的依赖关系,当一个 对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。从这段话里 我们可以得到两个信息,如下:
1, 观察者(具体执行操作的对象,有多个) 2, 被观察者(顾名思义是被观察的对象,如果该对象发生某些变化则通知观察者
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");
执行对应的操)
二、 jdk 中观察者模式解析
在 java 的 util 包中实现了该设计模式的框架,大部分应用都可以直接用它,当然了 你也可以自己实现它,实际上就是一个被观察者的抽象类和一个观察者接口。我们先看 一下 jdk 是如何实现的。被观察者的抽象类 java.util.Observable
package java.util; public class Observable { private boolean changed = false; private Vector obs;
public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } /**
* 通知操作,即被观察者发生变化,通知对应的观察者进行事先设定的操作,这个方法接受一个参数,这个 参数一直传到观察者里,以供观察者使用 */
下面是另一个观察者对象,表示顾客的手机,同样需要继承 Observer 接口 import java.util.Observable; import java.util.Observer; public class BuyerMobileMessage implements Observer {
private String buyerId = ""; private String mobileNo = "";
三、观察者模式应用
下面是一个 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) { = name; }