本篇文章大部分摘录自 http://c.biancheng.net/view/1390.htmlhtml
在现实世界中,许多对象并非独立存在的,其中一个对象的行为发生改变可能会致使一个或者多个其余对象的行为也发生改变。例如,某种商品的物价上涨时会致使部分商家高兴,而消费者伤心;还有,当咱们开车到交叉路口时,遇到红灯会停,遇到绿灯会行。这样的例子还有不少,例如,股票价格与股民、微信公众号与微信用户、气象局的天气预报与听众、小偷与警察等。java
在软件世界也是这样,例如,Excel 中的数据与折线图、饼状图、柱状图之间的关系;MVC 模式中的模型与视图的关系;事件模型中的事件源与事件处理者。全部这些,若是用观察者模式来实现就很是方便。微信
观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都获得通知并被自动更新。这种模式有时又称做发布-订阅模式、模型-视图模式,它是对象行为型模式。ide
观察者模式是一种对象行为型模式,其主要优势以下。测试
它的主要缺点以下。.net
实现观察者模式时要注意具体目标对象和具体观察者对象之间不能直接调用,不然将使二者之间紧密耦合起来,这违反了面向对象的设计原则。设计
观察者模式的主要角色以下。code
观察者模式的结构图如图 1 所示。server
天气做为该例子的主题,气象局、妈妈还有学生都是天气的观察者,天气发出提醒时,全部天气观察者都会作出回应。htm
// 抽象主题 public abstract class AbstractSubject { protected List<Observer> observerList = new ArrayList<>(); public void add(Observer observer) { observerList.add(observer); } public void remove(Observer observer) { observerList.remove(observer); } public abstract void notifyObservers(String status); } // 抽象观察者 public interface Observer { void response(String status); } // 具体主题 public class WeatherSubject extends AbstractSubject { @Override public void notifyObservers(String status) { for (Observer ob : observerList) { ob.response(status); } } } // 具体观察者 (气象局、妈妈、学生) public class WeatherCenterObserver implements Observer { @Override public void response(String status) { if ("rain".equals(status)) System.out.println("气象局:要下雨了!"); else System.out.println("气象局:天气晴朗!"); } } // 妈妈 public class MomObserver implements Observer { @Override public void response(String status) { if ("rain".equals(status)) System.out.println("妈妈:下雨了!回家收衣服!"); else System.out.println("妈妈:好天气,晒衣服!"); } } // 学生 public class StudentObserver implements Observer { @Override public void response(String status) { if ("rain".equals(status)) System.out.println("学生党:下雨了,出门带伞!"); else System.out.println("学生党:天气好!不用带伞出门!"); } }
测试例子
public static void main(String[] args) { AbstractSubject weatherSubject = new WeatherSubject(); weatherSubject.add(new WeatherCenterObserver()); weatherSubject.add(new MomObserver()); weatherSubject.add(new StudentObserver()); weatherSubject.notifyObservers("rain"); } // 输出结果: // 气象局:要下雨了! // 妈妈:下雨了!回家收衣服! // 学生党:下雨了,出门带伞!
我只作了一个简单的例子便于理解观察者模式,实际使用中,每每经过JMS和MQ来辅助实现观察者模式,而且须要事件相关对象的传导(使用泛型),这都是更高级的设计里须要考虑到的。
经过前面的分析与应用实例可知观察者模式适合如下几种情形。
在 Java 中,经过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就能够编写观察者模式实例。
Observable 类是抽象目标类,它有一个 Vector 向量,用于保存全部要通知的观察者对象,下面来介绍它最重要的 3 个方法。
Observer 接口是抽象观察者,它监视目标对象的变化,当目标对象发生变化时,观察者获得通知,并调用 void update(Observable o,Object arg) 方法,进行相应的工做。