观察者模式是非常常用的一种设计模式。在软件系统中,当一个对象的行为依赖于另一个对象的状态时,观察者模式就相当有用。若不适用观察者模式提供的通用结构,而需要实现其类似的功能,则只能在另一个线程中不停监控对象一来的状态。在一个复杂的系统中,可能会因此开启很多线程来实现这一个功能,这将使系统的性能产生额外的负担。观察者模式的意义也就在此,它可以在单线程中,使某一对象,及时得知自身所依赖的状态的变化。
观察者模式角色如下:
1.主题接口:指被观察的对象。当其状态发生改变或者某件事发生时,它会将这个变化通知观察者。它维护了观察者所需要依赖的状态。
2.具体主题:具体主题实现了主题接口中的方法。如新增观察者、删除观察者和通知观察者。其内部维护一个观察者列表。
3.观察者接口:观察者接口定义了观察者的基本方法。当依赖状态发生改变时,主题接口就会调用观察者的update()方法。
4.具体观察者:实现了观察者接口的update()方法,具体处理当被观察者状态改变或者某一件事情发生时的业务逻辑。
下面我们就用具体的代码来实现一个观察者模式:
主题接口的实现如下:
public interface ISubject{
void attach(IObserver observer);
void detach(IObserver observer);
void inform();
}
观察者接口实现如下:
public interface IObserver{
void update(Event evt);
}
一个具体的主题实现,注意,它维护了观察者队列,提供了增加和删除观察者的方法并通过inform()通知观察者。
public class ConcreteSubject implements ISubject{
Vector<IObserver> observers = new Vector<IObserver>();
public void attach(IObserver observer){
observers.addElement(observer);
}
public void detach(IObserver observer){
observers.removeElement(observer);
}
public void inform(){
Event event = new Event();
for(IObserver ob:observers){
ob.update(event);
}
}
}
一个具体的观察者实现如下,当其监听的状态发生改变时,update()方法就会被主题回调,进而可以在观察者内部进行业务逻辑的处理。
public class ConcreteObserver implements IObserver{
public void update(Event evt){
System.out.println("observer receives information");
}
}
观察者模式如此常用,以致于JDK内部就已经为我们准备了一套观察者模式实现。它位于java.util包中,包括java.util.Observable类和java.util.Observer接口。
在java.util.observable类中,已经实现了主要功能,如增加观察者、删除观察者和通知观察者,我们可以直接通过继承Observable使用这些功能。java.util.Observer接口是观察者接口,它的update()方法会在java.util.Observabel的notifyObservers()方法中被回调,以获得最新的状态变化。通常在观察者模式中Observer接口总是应用程序的核心扩展对象。具体的业务逻辑总是会被封装在update()方法中。