`
0428loveyu
  • 浏览: 30835 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

概述

观察者模式(Observer Pattern)是一个非常有用的模式,在Java语言当中,有许多地方用到了这一模式,比如Swing当中的事件模型。这一模式其实是建立在观察者模式基础之上的。这篇文章就来看看这个模式的一些基本的东西。

定义:

这个模式主要用来定义对象之间的一种一对多的依赖关系。当一个对象的状态发生改变的时候,所以依赖于它的对象得到通知并且自动更新。也称为发布-订阅模式(Publish-Subscribe)。这种模式使得对象之间的关系非常松,也就是松耦合。如下图:

结构:

该模式中的四个参与者分别为:目标(Subject)、具体目标(Concrete Subject)、观察者(Observer)、具体观察者(Concrete Observer)。

分别介绍如下:
  • Subject:Subject知道它的观察者,一个目标可以有多个观察者。(其实,一个观察者也可以对应多个目标,因此定义中一对多的说法并不是很准确。Subject还提供注册和删除观察者对象的接口。
  • Concrete Subject: 将观察者感兴趣的状态存入观察者对象,当状态改变的时候,通知各个观察者。
  • Observer: 定义一个更新接口
  • Concrete Observer: 维护一个指向ConcreteSubject对象的引用,存储有关的状态,实现Observer接口中的更新接口。

Java类库中的实现:

Java类库中对观察者模式提供的支持并没有完全按照上面的描述。

Observer接口:

对于观察者,它提供了一个Observer接口,位于java.util包中,之定义了一个update方法。如下:

void update(Observable o, Object arg);

有2个参数,其中Observable是目标的引用,可以通过这一引用获取目标的状态或者进行其他操作。Object是一个与具体实现逻辑相关的对象引用,也用于传递操作相关的信息。

Observable类:

Java中没有提供目标的接口,而是直接提供一个类。这样做有好有坏,我们就可以省去许多代码,同时也失去了一定的灵活性。来看一下这个类提供的各个方法;
注册、删除观察者:
以下三个方法用于注册、删除观察者,返回观察者数量等。
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

这个类采用Vector类型(私有与obs)来维护所有观察者的引用。很明白,增加一个观察者。
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

死一个方法删除一个观察者,后一个方法删除全部观察者。一样简单明了。
    public synchronized int countObservers() {
        return obs.size();
    }

返回观察者数量,没什么可说的。

有关目标状态的几个方法:
通过私有的布尔类型变量changed来判断、操作。
    public synchronized boolean hasChanged() {
        return changed;
    }

查看当前目标状态是否改变。
    protected synchronized void setChanged() {
        changed = true;
    }

设置状态改变标志位true。
    protected synchronized void clearChanged() {
        changed = false;
    }

清空状态改变标志位。
注意一下各个方法的访问控制符,具体实现的时候小心使用。

通知观察者:
这些方法通知观察者。其实就是调用观察者的update方法,并将改变标志位清空。通知所有观察者,可以传递一个对象用于交互。如下:
    public void notifyObservers(Object arg) {
        /*
         * a temporary array buffer, used as a snapshot of the state of
         * current Observers.
         */
        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 void notifyObservers() {
        notifyObservers(null);
    }

一样很明了,比较麻烦的就是多线程的问题了,不多说。

一个简单例子:

下面是一个最简单的例子。DataStore作为目标,Screen作为观察者,同时有一个特殊的观察者SpecialScreen,这个观察着在第一次得到通知之后就把自己从观察者中删除。
DataStore:
import java.util.Observable;

/**
 * @author Brandon B. Lin
 *
 */
public class DataStore extends Observable {
	private String data;

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
		/*mark the abservable as changed*/
		setChanged();
	}

}

Screen:
import java.util.Observable;
import java.util.Observer;

/**
 * @author Brandon B. Lin
 *
 */
public class Screen implements Observer {

	protected int observerId;

	public Screen(int observerId) {
		this.observerId = observerId;
	}

	@Override
	public void update(Observable o, Object arg) {
		// act on the update
		System.out.println(observerId + ": The subject has changed!");

	}

}

SpecialScreen:
import java.util.Observable;

public class SpecialObserver extends Screen {

	public SpecialObserver(int observerId) {
		super(observerId);
	}

	@Override
	public void update(Observable o, Object arg) {
		// act on the update
		System.out.println(observerId
				+ ": The subject has changed! and I will leave!");
		o.deleteObserver(this);

	}

}

Test:
/**
 * @author Brandon B. Lin
 * 
 */
public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		DataStore dataStore = new DataStore();
		Screen[] screens = new Screen[10];
		for (int i = 0; i < 10; i++) {
			if (i == 5) {
				screens[i] = new SpecialObserver(i);
			} else {
				screens[i] = new Screen(i);
			}

			dataStore.addObserver(screens[i]);
		}

		dataStore.setData("new data");
		dataStore.notifyObservers();

		dataStore.setData("Latest data");
		dataStore.notifyObservers();

	}

}

参考资料:

《设计模式:可复用面向对象软件的基础》
JDK源码

声明:版权所有,转载务必注明出处,本作者保留一切法律权利。

分享到:
评论

相关推荐

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

    观察者模式,也被称为发布-订阅模式或事件驱动模式,是软件设计模式中的一种行为模式。这个模式的主要目的是在对象之间建立一种松散耦合的关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并...

    [行为模式]head first 设计模式之观察者模式(observer)

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式在软件开发中广泛应用于事件驱动...

    详解Observer Pattern(观察者模式)在Java中的使用原理

    我们说学习Java应该从Swing开始,那么学习Swing最重要的思想就是对于观察者模式的理解(Observer Pattern)。因为,该设计模式在Java Swing框架中贯穿了始终。对于C#的委托、代理概念所使用的Callback(回调模式--...

    java23种设计模式之观察者模式

    **观察者模式(Observer Pattern)**是软件设计模式中的一种行为模式,它在Java中有着广泛的应用。这个模式的核心思想是“一对多”的依赖关系,即一个主题对象(Subject)可以被多个观察者(Observer)关注,当主题...

    设计模式之观察者模式Java实现

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于事件驱动的系统或者...

    PHP设计模式之观察者模式(Observer)详细介绍和代码实例

    观察者模式是一种行为设计模式,它定义了对象间的一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式经常用于实现软件的分布式事件通知系统,例如,图形...

    观察者模式,Observer

    观察者模式(Observer Pattern)是设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式常用于实现事件驱动的系统或者...

    设计模式实现——观察者模式

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现发布-订阅...

    设计模式之观察者模式

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件驱动的编程...

    设计模式-观察者模式-作业-observer.zip

    观察者模式(Observer Pattern)是软件设计模式中的行为模式之一,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件驱动或发布-...

    Unity3D设计模式之观察者模式

    观察者模式(Observer Pattern)是一种软件设计模式,属于行为型模式之一。它定义了对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式可以有效地实现...

    JavaScript编程设计模式之观察者模式(Observer Pattern)实例详解

    主要介绍了JavaScript编程设计模式之观察者模式(Observer Pattern),简单说明了观察者模式的概念、原理并结合实例形式详细给出了观察者模式的相关实现与使用技巧,需要的朋友可以参考下

    C#面向对象设计模式纵横谈(19):(行为型模式) Observer 观察者模式 (Level 300)

    **C#面向对象设计模式纵横谈(19)**:**观察者模式**(Observer Pattern)是行为型模式的一种,它在软件工程中扮演着至关重要的角色。观察者模式是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态...

    设计模式-观察者

    观察者模式(Observer Pattern)是行为设计模式的一种,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式的核心思想是发布-订阅模型,其中...

    设计模式之观察着模式Observer

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件驱动的编程...

    设计模式之Observer - 观察者模式

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件驱动编程或者...

    OBserver模式设计实现

    观察者模式(Observer Pattern)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在Java和C++等面向对象编程语言中,这种模式广泛用于事件处理和实时系统,...

Global site tag (gtag.js) - Google Analytics