【设计模式系列】浅析观察者模式

我是研究僧i 提交于 2019-11-28 20:31:44

        观察者<Observer>模式(有时又被称为发布-订阅<Publish/Subscribe>模式、模型-视图<Model/View>模式、源-收听者<Source/Listener>模式或从属者<Dependents>模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统



Subject(被观察的对象接口)  

        规定ConcreteSubject的统一接口;

        每个Subject可以有多个Observer

ConcreteSubject(具体被观察对象)

        维护对所有具体观察者的引用的列表;

        状态发生变化时会发送通知给所有注册的观察者。

Observer(观察者接口)

        规定ConcreteObserver的统一接口;

        定义了一个update()方法,在被观察对象状态改变时会被调用。

ConcreteObserver(具体观察者)

       维护一个对ConcreteSubject的引用;

        特定状态与ConcreteSubject同步;

        实现Observer接口,通过update()方法接收ConcreteSubject的通知。


模式的应用场景和优缺点:

观察者模式的应用场景:

1、对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。

2、对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。

观察者模式的优点:

1SubjectObserver之间是松偶合的,分别可以各自独立改变。

2Subject在发送广播通知的时候,无须指定具体的ObserverObserver可以自己决定是否要订阅Subject的通知。

3、遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

观察者模式的缺陷:

1、松偶合导致代码关系不明显,有时可能难以理解。(废话)

2、如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题。(毕竟只是简单的遍历)

简单实现观察者模式

package designpattern;

import java.util.Vector;

/**
 * @author lei 2011-10-18
 * 观察者<Observer>模式(
 * 称为
 * 	 发布-订阅<Publish/Subscribe>模式、
 * 	 模型-视图<Model/View>模式、 
 * 	 源-收听者<Source/Listener>模式或
 *   从属者<Dependents>模式)
 * 是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,
 * 并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。
 * 此种模式通常被用来实作事件处理系统
 */
public class ObserverTest {

	public static void main(String[] args) {
		//新建一个被观察者对象,继承了MyObserver,代表是可观察对象,其保存了观察者的信息,及触发观察者做出反映
		Subject subject = new Subject();
		//添加观察者
		subject.addObserver(new MailServer());
		//被观察对象执行方法,同时触发观察者动作
		subject.doSomething();
	}

}
//观察者接口,定义了观察者统一的方法
interface MyObserver {

	public void update(MyObservable o, Object arg);

}
//可观察对象类,定义了观察者及是否发生改变
class MyObservable {

	protected boolean change;
	//保存通知者
	protected Vector<MyObserver> observers;

	MyObservable() {
		observers = new Vector<MyObserver>();
	}

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

	public void romoveObservers(MyObserver obServer) {
		observers.remove(obServer);
	}

	public void romoveAllObservers() {
		observers.removeAllElements();
	}

	//通知观察者发生改变,并执行动作
	public void notifyObservers(Object arg) {
		Object[] arrays = null;
		//同步可观察者对象,同时清除改变
		synchronized (this) {
			if (!change)
				return;
			arrays = observers.toArray();
			clearChange();
		}
		//通知观察者不需要同步
		for (Object obServer : arrays) {
			((MyObserver) obServer).update(this, arg);
		}
	}

	protected synchronized void addObserver(MyObserver obServer) {
		observers.add(obServer);
	}

	protected synchronized void setChanged() {
		change = true;
	}

	protected synchronized void clearChange() {
		change = false;
	}

	protected synchronized boolean hasChanged() {
		return change;
	}

}
//通知者
class MailServer implements MyObserver {

	public void update(MyObservable o, Object arg) {
		System.out.println("send mail!");
	}

}
//被观察者
class Subject extends MyObservable {

	//执行时,同时通知观察者
	public void doSomething() {
		System.out.println("do something!");
		setChanged();
		notifyObservers();
	}

}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!