设计模式-02-观察者模式

观察者模式,顾名思义,就是有人在做,有人在看。所以,观察者模式涉及到两个群体,观察者和被观察者,比如说订阅新闻,某网站提供新闻拱客户阅读,只要客户订阅了该网站新闻,每当网站提供新的新闻素材时,就会通知客户,客户收到相应通知后更新新闻列表,如果客户取消订阅,那么网站有更新时,客户就不会收到新闻,这里网站就是被观察者,客户就是观察者,他们以及他们之间的订阅关系构成了观察者模式的一个例子。


定义:观察者模式定义了对象之间的一对多的依赖关系,当一个对象更新时,所以的依赖于该对象的对象都会收到通知并自动更新。

从定义可以看出,被观察者是一对多关系的一那一端。

UML图:



 
从图中我们可以看到,主题只依赖观察者接口,这里又一次遵循了松耦合原则,只要具体的观察这类实现观察者接口,那么主题和观察者直接就能交互,无论具体观察者实现类如何变化,记住,解耦是设计模式中最最基本的原则之一。

例子:

package subject;

import observer.MyObserver;

/**
 * 主题
 * 
 * @author 梅东
 * 
 */
public interface Subject {
	/**
	 * 注册观察者
	 * 
	 * @param observer
	 */
	void registerObserver(MyObserver observer);

	/**
	 * 移除观察者
	 * 
	 * @param observer
	 */
	void removeObserver(MyObserver observer);

	/**
	 * 通知观察者更新信息
	 */
	void notifyObservers();
}


package observer;

/**
 * 观察者
 * 
 * @author 梅东
 * 
 */
public interface MyObserver {
	/**
	 * 接收主题消息后执行更新操作
	 */
	void update();
}


package subject;

import java.util.ArrayList;
import java.util.List;

import observer.MyObserver;

public class ConcreteSubject implements Subject {

	private List<MyObserver> observers = new ArrayList<MyObserver>();

	@Override
	public void registerObserver(MyObserver observer) {
		observers.add(observer);
	}

	@Override
	public void removeObserver(MyObserver observer) {
		observers.remove(observer);
	}

	@Override
	public void notifyObservers() {
		for (MyObserver observer : observers) {
			observer.update();
		}
	}

	public void stateChanged() {
		notifyObservers();
	}
}


package observer;

import subject.Subject;

public class MyObserverImpl_A implements MyObserver {
	private Subject subject;

	/**
	 * 在构造函数中注册主题
	 * 
	 * @param subject
	 */
	public MyObserverImpl_A(Subject subject) {
		this.subject = subject;
		this.subject.registerObserver(this);
	}

	@Override
	public void update() {
		System.out.println("A 接收到了新的订阅消息");
	}

}


package observer;

import subject.Subject;

public class MyObserverImpl_B implements MyObserver {
	private Subject subject;

	/**
	 * 在构造函数中注册主题
	 * 
	 * @param subject
	 */
	public MyObserverImpl_B(Subject subject) {
		this.subject = subject;
		this.subject.registerObserver(this);
	}

	@Override
	public void update() {
		System.out.println("B 接收到了新的订阅消息");
	}

}


package test;

import observer.MyObserver;
import observer.MyObserverImpl_A;
import observer.MyObserverImpl_B;
import subject.ConcreteSubject;

public class TestDriver {

	public static void main(String[] args) {
		ConcreteSubject subject = new ConcreteSubject();
		MyObserver observerA = new MyObserverImpl_A(subject);
		MyObserver observerB = new MyObserverImpl_B(subject);
		subject.stateChanged();
		System.out.println("observerB对象取消订阅主题=================>");
		subject.removeObserver(observerB);
		subject.stateChanged();
	}

}

运行结果:
A 接收到了新的订阅消息
B 接收到了新的订阅消息
observerB对象取消订阅主题=================>
A 接收到了新的订阅消息

在具体的主题实现中,使用了ArrayList来存储注册的观察者对象,在观察者构造函数中,直接订阅主题。测试结果表明,每次主题状态发生改变后,观察者都会收到通知,并执行相应操作,在移除观察者observerB后,主题发生改变后,observerB并没有收到通知,只有注册的observerA才收到通知。

观察这模式也很简单,但是应用很广泛,最常见的就是图形编程中的事件机制,有兴趣的朋友可以深入研究。 

猜你喜欢

转载自zhanyf.iteye.com/blog/1381553