接下来是Observer 模式。
Observer,观察者模式,这个模式在面向对象设计中使用的相当普遍,它遵循OCP、LSP、ISP等设计原则。
下面使用一个日常生活中的示例来讲解一下观察者模式。
Observer1:Firer(消防员)
Subject:Building(大厦)
消防员来时刻关注大厦的情况,一旦出现火灾,必须马上响应——response()。但是消防员不能一天24小时盯着大厦,最好是大厦在出现火灾时,能主动提示一下——notify()。怎么做到这一点呢,比较常规的办法就是安装一个火灾预警器——register(),一旦出现火灾,给出警报。这里用的就是Observer 模式,如此而已。
扩展一下,假如大厦还需要工程维修人员,大厦出现问题时需要人员维修。
Observer2:Worker(工程维修人员)
Subject:Building(大厦)
跟上一种情况类似,无非是再给大厦添加一种报告装置——register2()。
观者者模式有2种模型:
拉模型,比较简单,还是使用消防员和大厦的例子,如果是拉模式,那么消防员response() 的时候需要知道哪里出了问题,一般来说,火灾比较明显,所以这里就直接知道了问题所在。但是,如果是工程维修人员响应大厦维修工作,那么他必须至少知道是楼要倒塌了还是某块地板坏了。拉模式就不再适用了。
推模型,在notify() 的时候,加上一个额外的信息,告诉Observer 进一步的response() 处理信息。
选择哪种模型完全取决于被观察者的复杂程度。如果比较复杂,而且需要一个提示给观察者,那么推模型是更好的选择。
代码:(拉模型)
public asbtract class Subject
{
private List<Observer> observers = new LinkedList<Observer>();
public void register(Observer observer)
{
this.observers.add(observer);
}
public void notify()
{
for(Observer observer: observers)
{
observer.response();
}
}
}
public interface Observer
{
void response();
}
推模型只是给notify() 和 response() 方法加上参数即可。