观察者模式
模式说明
结构
代码演示
package com.yukiyama.pattern.behavior;
import java.util.ArrayList;
import java.util.List;
/**
* 观察者模式
*/
public class ObserverDemo {
public static void main(String[] args) {
// 声明一个具体目标对象,人民币汇率
Rate rate = new RMBRate();
// 声明两个不同的观察者对象,进口公司和出口公司
Company watcher1 = new ImportCompany();
Company watcher2 = new ExportCompany();
// 将观察者都加入到目标对象中,以便目标能够在自身产生变化时通知所有观察者
rate.add(watcher1);
rate.add(watcher2);
// 当汇率升高3.5%时,进出口公司分别对这个变化做出应对
rate.change(0.035);
// 当汇率下降6.8%时,进出口公司分别对这个变化做出应对
rate.change(-0.068);
}
}
/**
* 抽象目标类(被观察事物)
* 持有一个观察者类实例的集合,实现两个非抽象方法,add方法用来添加观察者
* 实例,remove方法用来删除观察者实例。另有一个抽象方法change,传入变化。
*/
abstract class Rate{
protected List<Company> companies = new ArrayList<>();
public void add(Company company) {
companies.add(company);
}
public void remove(Company company) {
companies.remove(company);
}
public abstract void change(double changedRate);
}
/**
* 具体目标类
* 继承抽象目标类,实现抽象方法change,在方法内遍历其持有的所有观察者,
* 传入变化,执行观察者的action方法。
*/
class RMBRate extends Rate{
@Override
public void change(double changedRate) {
System.out.printf("人民币汇率变动%.1f%%\n", changedRate*100);
for(Company company : this.companies) {
company.action(changedRate);
}
}
}
/**
* 抽象观察者类
* 持有一个name属性,并有对应的getter/setter。定义了一个action抽象方法。
* 下例以公司为抽象观察者类。
*/
abstract class Company{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void action(double changedRate);
}
/**
* 具体观察者类
* 通过无参构造器初始化name。实现抽象观察者类中的抽象方法action。
* 下例是进口公司观察者,action内实现当人民币汇率降低时减少相应比例
* 的进口量,升高时增加相应比例的进口量。
*/
class ImportCompany extends Company{
public ImportCompany() {
this.setName("进口公司");
}
@Override
public void action(double changedRate) {
System.out.printf("%s动作:\n", this.getName());
if(changedRate < 0) {
System.out.printf("人民币汇率下降了%.1f%%,减少%.1f%%进口量。\n",
-changedRate*100, -changedRate*100);
} else {
System.out.printf("人民币汇率上升了%.1f%%,增加%.1f%%进口量。\n",
changedRate*100, changedRate*100);
}
}
}
/**
* 具体观察者类
* 下例是出口公司观察者,action内实现当人民币汇率降低时增加相应比例
* 的进口量,升高时减少相应比例的进口量。
*/
class ExportCompany extends Company{
public ExportCompany() {
this.setName("出口公司");
}
@Override
public void action(double changedRate) {
System.out.printf("%s动作:\n", this.getName());
if(changedRate < 0) {
System.out.printf("人民币汇率下降了%.1f%%,增加%.1f%%出口量。\n",
-changedRate*100, -changedRate*100);
} else {
System.out.printf("人民币汇率上升了%.1f%%,下降%.1f%%出口量。\n",
changedRate*100, changedRate*100);
}
}
}Last updated