观察者模式
概念
观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
顾客对某个特定品牌的产品非常感兴趣(例如最新型号的 iPhone 手机),而该产品很快将会在商店里出售。
顾客可以每天来商店看看产品是否到货。但如果商品尚未到货时,绝大多数来到商店的顾客都会空手而归。另一方面,每次新产品到货时,商店也可以向所有顾客发送邮件(可能会被视为垃圾邮件)。这样,部分顾客就无需反复前往商店了,但也可能会惹恼对新产品没有兴趣的其他顾客。
似乎遇到了一个矛盾:要么让顾客浪费时间检查产品是否到货,要么让商店浪费资源去通知没有需求的顾客。
观察者模式建议,为发布者类添加订阅机制,让每个对象都能订阅或取消订阅发布者事件流。
观察者模式结构
观察者模式实例:人民币汇率
利用观察者模式设计一个程序,分析“人民币汇率”的升值或贬值对进口公司进口产品成本,或出口公司的出口产品收入的影响。
当“人民币汇率”升值时,进口公司的进口产品成本降低且利润率提升,出口公司的出口产品收入降低且利润率降低;当“人民币汇率”贬值时,进口公司的进口产品成本提升且利润率降低,出口公司的出口产品收入提升且利润率提升。
- 这里的汇率(Rate)类是抽象目标类,它包含了保存观察者(Company)的List和增加/删除观察者的方法,以及有关汇率改变的抽象方法
change(int number); - 而人民币汇率(RMBrate)类是具体目标,它实现了父类的
change(int number)方法,即当人民币汇率发生改变时通过相关公司; - 公司(Company)类是抽象观察者,它定义了一个有关汇率反应的抽象方法
response(int number); - 进口公司(ImportCompany)类和出口公司(ExportCompany)类是具体观察者类,它们实现了父类的
response(int number)方法,即当它们接收到汇率发生改变的通知时作为相应的反应。
订阅者及具体订阅者
package observer;
/**
* 抽象观察者:公司
* @author chenzufeng
* @date 2021-2-8
*/
public interface Company {
/**
* 对汇率的反应
* @param number 汇率
*/
void response(int number);
}
出口公司:
package observer;
public class ExportCompany implements Company {
@Override
public void response(int number) {
if (number > 0) {
System.out.println("人民币汇率升值" + number + "个基点,降低了出口产品收入,降低了出口公司的销售利润率。");
} else if (number < 0) {
System.out.println("人民币汇率贬值" + (-number) + "个基点,提升了出口产品收入,提升了出口公司的销售利润率。");
}
}
}
进口公司:
package observer;
public class ImportCompany implements Company {
@Override
public void response(int number) {
if (number > 0) {
System.out.println("人民币汇率升值" + number + "个基点,降低了进口产品成本,提升了进口公司利润率。");
} else if (number < 0) {
System.out.println("人民币汇率贬值" + (-number) + "个基点,提升了进口产品成本,降低了进口公司利润率。");
}
}
}
发布者
package observer;
import java.util.ArrayList;
import java.util.List;
/**
* 抽象目标:汇率
*/
abstract class Rate {
protected List<Company> companyList = new ArrayList<>();
/**
* 增加观察者
* @param company 公司
*/
public void addCompany(Company company) {
companyList.add(company);
}
/**
* 删除观察者
* @param company 公司
*/
public void removeCompany(Company company) {
companyList.remove(company);
}
/**
* 汇率改变
* @param number 汇率
*/
public abstract void change(int number);
}
package observer;
/**
* 具体目标:人民币汇率
*/
public class RMBrate extends Rate {
@Override
public void change(int number) {
for (Company company : companyList) {
company.response(number);
}
}
}
客户端
package observer;
public class Client {
public static void main(String[] args) {
Rate rate = new RMBrate();
Company company1 = new ImportCompany();
Company company2 = new ExportCompany();
rate.addCompany(company1);
rate.addCompany(company2);
rate.change(10);
rate.change(-5);
}
}

浙公网安备 33010602011771号