一、概述
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设计模式——观察者模式的两种情况": 1. **主动通知**: 在这种情况下,被观察者对象在自身状态发生变化时,会主动调用`Observable`接口提供的`notifyObservers()`方法,将变化通知给所有注册的...
在《设计模式实现——观察者模式》这篇博客中,作者可能详细解释了观察者模式的概念、结构以及其在实际编程中的应用。以下是对观察者模式的详细阐述: 1. **模式定义**:观察者模式是一种对象行为型模式,它允许...
本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...
《Java与模式——源码》这个主题涉及到的是Java编程语言中的设计模式应用,以及如何通过源代码来理解和学习这些模式。设计模式是软件工程中的一种最佳实践,它们是解决常见问题的经验总结,使得代码更易读、易维护、...
在编程世界中,Java设计模式是面向对象编程领域的一个重要概念,它为解决常见的软件设计问题提供了可重用的解决方案。对于新手来说,设计模式可能显得深奥难懂,但它们实际上是经验丰富的开发者用来提高代码质量、可...
《设计模式——Java语言中的应用》是一本专为Java开发者深入理解面向对象设计而编写的经典书籍。设计模式是软件工程领域中经过实践验证的、解决常见问题的有效方案,它们代表了在特定上下文中,针对特定问题的最优...
《Java设计模式》是刘伟老师的一本经典教材,它深入浅出地讲解了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的通用解决方案,是软件开发中的智慧结晶。这本书的课后习题和...
在本文中,我们将深入探讨设计模式中的一个经典案例——观察者模式(Observer Pattern),通过具体的实现来理解其工作原理。观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生...
本文将深入探讨其中的一种——观察者模式(Observer Pattern)。观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 ### ...
本文将深入探讨其中的一种——观察者模式(Observer Pattern),它是行为设计模式的一种,主要用来封装行为的变化,实现对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被...
《设计模式——观察者》 在软件工程中,设计模式是一种在特定情境下解决常见问题的经验总结,它们是经过反复验证的最佳实践。观察者模式(Observer Pattern)是行为设计模式的一种,它定义了对象之间的一对多依赖...
观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式在软件开发中广泛应用于事件驱动...
### JAVA设计模式总结之23种设计模式及六大原则 #### 一、设计模式之六大原则 ##### 总原则:开闭原则(Open Close Principle) 开闭原则是设计模式中最核心的原则之一,它强调的是软件实体(类、模块、函数等)...
### Java设计模式经典教程知识点概览 #### 一、设计模式概述 设计模式是一种软件设计方法,它为软件开发者提供了一种标准化的方式去解决常见的软件设计问题。设计模式的使用可以提高代码的可读性和可维护性,同时...
Java设计模式是软件开发中的重要概念,它是一种在特定情境下解决问题的经验总结,可以提高代码的可读性、可维护性和可复用性。在这个压缩包文件“DesignPatterns”中,很可能包含了各种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 门面...
在本文中,我们将深入探讨设计模式中的"观察者模式",并以`WeatherData`为例进行具体实现。观察者模式是一种行为设计模式,它允许我们定义一个订阅机制,当对象状态发生变化时,可以通知所有依赖它的观察者。这种...