在软件系统中,当一个对象的行为依赖于另一方个对象的状态时,观察者模式就相当有用。若不使用观察者模式提供的通用结构,而需要实现其类似的功能,则只能在另一个线程中不停的监听对象所依赖的状态。在一个复杂系统中,可能因此开启很多线程来实现这一功能,这使系统的性能产生额外的负担。观察者模式的意义在于:在单线程中,使某一对象,及时得知自身所依赖的状态的变化。
观察者模式可以用于事件监听、通知发布等场合。可以确保观察者在不使用轮询监控的情况下,及时收到相关消息和事件。
观察者模式角色:主题接口—-指被观察的对象,当其状态发生改变或者某事件发生时,它会将这个变化通知观察者,维护了观察者所需要的依赖的状态;具体主题—-具体主题实现了主题接口中的方法,如新增观察者、删除观察者和通知观察者,其内部维护了一个观察者列表;观察者接口—-定义了观察者的基本方法,当依赖状态发生改变时,主题接口就会调用观察者的方法;具体观察者—-实现了观察者接口中的方法,具体参照自身的业务逻辑。
优点:观察者模式接触了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体,从而使得各自的变化都不会影响另一边的变化。缺点:依赖关系并未完全接触,抽象通知者依旧依赖抽象的观察者。
自定义的观察者例子
主题接口:
public interface ISubject {
//添加观察者
void attach(IObserver observer);
//删除观察者
void detach(IObserver observer);
//通知所有观察者
void inform();
}
观察者接口:
public interface IObserver {
void update();
}
具体主题:
/**
* 具体的主题实现 维护了观察者队列,提供了增加和删除观察者的方法并使用inform()通知观察者
* @author qiaolin
*
*/
public class ConcreteSubject implements ISubject{
private Vector<IObserver> observers = new Vector<IObserver>();
public void attach(IObserver observer) {
observers.add(observer);
}
public void detach(IObserver observer) {
observers.remove(observer);
}
public void inform() {
for(IObserver observer:observers){
observer.update();//观察者的更新
}
}
}
具体观察者:
package com.performance.optimization.design.observer;
/**
* 具体的观察者
* @author qiaolin
*
*/
public class ConcreteObserver implements IObserver{
public void update() {
System.out.println("Observer receivers information");
}
}
自定义测试:
@Test
public void test(){
ConcreteSubject subject = new ConcreteSubject();
subject.attach(new ConcreteObserver());//观察者加入
subject.attach(new ConcreteObserver());//添加观察者
subject.inform();//通知观察者
}
Jdk自带的观察者
Jdk自带的Observable实现了具体主题的主要功能,如增加、删除和通知观察者,Observer接口是观察者接口,update方法会在Observerable类中的notifyObservers方法中回调,在自定义具体主题时,需要通知观察者,则必须先调用setChanged方法。
Jdk自定义的具体主题:
/**
* jdk自带的 具体主题
* @author qiaolin
*
*/
public class JdkSubject extends Observable{
@Override
public synchronized void addObserver(Observer o) {
super.addObserver(o);
}
@Override
public void notifyObservers(Object args) {
super.setChanged();//状态发生改变
super.notifyObservers(args);//通知所有观察者
}
}
Jdk自定义的具体观察者:
/**
* jdk具体的观察者
* @author qiaolin
*
*/
public class JdkObserver implements Observer{
public void update(Observable o, Object arg) {
System.out.println("Jdk 自带的观察者通知消息");
}
}
Jdk自定义的观察者测试:
@Test
public void testJDK(){
JdkSubject subject = new JdkSubject();
subject.addObserver(new JdkObserver());
subject.addObserver(new JdkObserver());
//通知所有观察者
subject.notifyObservers(null);
}