`

设计模式学习笔记——观察者模式

阅读更多

观察者模式

又叫发布-订阅模式 源-监听器模式 从属模式等等

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当这个主体对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

 

观察者模式中有以下这些角色:

Subject抽象主题角色:主题角色将所有的观察者对象的引用保存在一个聚集里,提供增删的接口。

Observer抽象观察者角色:为所有观察者提供统一接口,在得到通知时更新自己。

ConcreteSubject具体主题角色:实现抽象主题Subject中定义的方法 包括维护一个聚合 通知其中的观察者等

ConcreteObserver抽象观察者:实现更新自己的方法 更具具体需要实现自身逻辑。

免责盗图:

具体代码实现

首先Subject抽象主题:

public interface Subject {
	void addObserver(Observer observer);
	void delObserver(Observer observer);
	void notifyObserver();
	void change();
}

 其中定义了主题类会用到的关于维护和通知observer聚合的方法

同样的Observer抽象观察者,其中只定义了一个update方法

public interface Observer {
	void update();
}

 而在具体实现操作的ConcreteObserver中,为了方便观察,我们让update方法答应出一句话

public class ConcreteObserver implements Observer{
	private String observerName;
	public ConcreteObserver(String name){
		this.observerName=name;
	}
	public void update() {
		System.out.println(observerName+" is notifyed");
	}
}

 ConcreteSubject的实现:

public class ConcreteSubject implements Subject{
	private Vector subjectVector=new Vector();
	public void addObserver(Observer observer) {
		subjectVector.addElement(observer);
	}

	public void delObserver(Observer observer) {
		subjectVector.removeElement(observer);
	}

	public void notifyObserver() {
		int s=subjectVector.size();
		for(int i=0;i<s;i++){
			((Observer)subjectVector.get(i)).update();
		}
	}
	
	public void change(){
		notifyObserver();
	}
}

 通过一个Vector来维护observer列表,并提供了add和del方法,用于绑定或撤销绑定。

实现的效果:

public class ObserverPattern {
	public static void main(String[] args){
		ConcreteSubject subject=new ConcreteSubject();
		ConcreteObserver observer1=new ConcreteObserver("observer1");		
		ConcreteObserver observer2=new ConcreteObserver("observer2");
		subject.addObserver(observer1);
		subject.addObserver(observer2);
		subject.change();
	}
}

 构件了2个observer,绑定到subject后,调用change方法表示subject状态的改变,最后输出结果

observer1 is notifyed

observer2 is notifyed

 

在Subject主题角色中,可继续加入诸如change标志位,记录subject状态的改变,这个可以参考Java提供的对观察者模式的支持

在Java中提供了java.uttl.Observable和java.util.Observer类提供观察者模式的支持

其中Observable在上面简单的例子上,添加了setChanged,clearChanged,hasChanged,countObserver等方法

其中Observable也就是上述的Subject,而Observer也和上述的Observer等同。

 

观察者模式的效果有以下的优点: 

1 观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,那么这个对象必然跨越抽象化和具体化层次。 

2 观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知, 

 

观察者模式有下面的缺点: 

1 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 

2 如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。 

4 虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。 

 

观察者模式应用非常广泛,最常见的在UI中,各种Listener就是观察者模式的一种,通过setListener将动作绑定到某个控件中,而当控件状态改变(被点击或是获得焦点等),会触发相应的Listener,从而执行应该有的动作。

  • 大小: 5.5 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics