观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都获得通知并被自动更新。这种模式有时又称做发布-订阅模式、模型-视图模式,它是对象行为型模式。java
观察者模式是一种对象行为型模式,其主要优势以下。测试
它的主要缺点以下。设计
实现观察者模式时要注意具体目标对象和具体观察者对象之间不能直接调用,不然将使二者之间紧密耦合起来,这违反了面向对象的设计原则。code
观察者模式的主要角色以下。server
观察者模式的结构图以下图所示:对象
利用观察者模式设计一个程序,分析“人民币汇率”的升值或贬值对进口公司的进口产品成本或出口公司的出口产品收入以及公司的利润率的影响。blog
分析:当“人民币汇率”升值时,进口公司的进口产品成本下降且利润率提高,出口公司的出口产品收入下降且利润率下降;当“人民币汇率”贬值时,进口公司的进口产品成本提高且利润率下降,出口公司的出口产品收入提高且利润率提高。接口
这里的汇率(Rate)类是抽象目标类,它包含了保存观察者(Company)的 List 和增长/删除观察者的方法,以及有关汇率改变的抽象方法 change(int number);而人民币汇率(RMBrate)类是具体目标, 它实现了父类的 change(int number) 方法,即当人民币汇率发生改变时经过相关公司;公司(Company)类是抽象观察者,它定义了一个有关汇率反应的抽象方法 response(int number);进口公司(ImportCompany)类和出口公司(ExportCompany)类是具体观察者类,它们实现了父类的 response(int number) 方法,即当它们接收到汇率发生改变的通知时做为相应的反应。rem
下图所示是其结构图:产品
程序代码以下
//测试类 public class RMBrateTest { public static void main(String[] args) { Rate rate=new RMBrate(); Company watcher1=new ImportCompany(); Company watcher2=new ExportCompany(); rate.add(watcher1); rate.add(watcher2); rate.change(10); rate.change(-9); } } //抽象目标:汇率 abstract class Rate { protected List<Company> companys=new ArrayList<Company>(); //增长观察者方法 public void add(Company company) { companys.add(company); } //删除观察者方法 public void remove(Company company) { companys.remove(company); } public abstract void change(int number); } //具体目标:人民币汇率 class RMBrate extends Rate { public void change(int number) { for(Company obs:companys) { ((Company)obs).response(number); } } } //抽象观察者:公司 interface Company { void response(int number); } //具体观察者1:进口公司 class ImportCompany implements Company { public void response(int number) { if(number>0) { System.out.println("人民币汇率升值"+number+"个基点,下降了进口产品成本,提高了进口公司利润率。"); } else if(number<0) { System.out.println("人民币汇率贬值"+(-number)+"个基点,提高了进口产品成本,下降了进口公司利润率。"); } } } //具体观察者2:出口公司 class ExportCompany implements Company { public void response(int number) { if(number>0) { System.out.println("人民币汇率升值"+number+"个基点,下降了出口产品收入,下降了出口公司的销售利润率。"); } else if(number<0) { System.out.println("人民币汇率贬值"+(-number)+"个基点,提高了出口产品收入,提高了出口公司的销售利润率。"); } } }
经过前面的分析与应用实例可知观察者模式适合如下几种情形。