一、应用场景
1、订阅火车票,需要发送日志,也需要发送短信;
2、微信朋友圈动态通知、邮件通知、消息通知等;
3、开发某个系统,用户注册成功后,给用户发放优惠券,后面需求变动:注册成功后,给用户发送邮件; 需求在不断变动,要求在注册成功后,执行的操作也越来越多;
二、观察者模式
2.1 模式说明
又被称为发布-订阅模式,当目标对象(被观察者)的状态发生改变时,它的所有观察者都会收到通知。一个目标对象可以有多个观察者。
图 观察者模式
2.2 代码实现
需求描述:一家证券公司有银行、基金公司、个人三个客户,当分析师写好报告后,系统会自动把报告发送给这三个客户;
图 需求实现
/** 被观察者 */
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver(String title);
}
/** 观察者 */
public interface Observer {
void update(String title);
}
/** 证券公司 */
public class SecuritiesCompany implements Subject{
private List<Observer> observerList = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observerList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observerList.remove(observer);
}
@Override
public void notifyObserver(String title) {
for(Observer observer : observerList) {
observer.update(title);
}
}
/**
* 完成报告
*/
public void finishReport() {
notifyObserver("第一篇报告");
}
}
/** 银行 */
public class Bank implements Observer{
public Bank(Subject subject) {
subject.registerObserver(this);
}
@Override
public void update(String title) {
System.out.println("银行收到:" + title);
System.out.println("我可以放贷款了");
}
}
/** 基金公司 */
public class FundCompany implements Observer{
public FundCompany(Subject subject) {
subject.registerObserver(this);
}
@Override
public void update(String title) {
System.out.println("基金公司收到:" + title);
System.out.println("我可以募集资金了");
}
}
/** 个人 */
public class People implements Observer{
public People(Subject subject) {
subject.registerObserver(this);
}
@Override
public void update(String title) {
System.out.println("个人收到:" + title);
System.out.println("我可以买股票了");
}
}
/** 交易市场 */
public class MarketPlace {
public static void main(String[] args) {
SecuritiesCompany zhongxin = new SecuritiesCompany();
Bank rmBank = new Bank(zhongxin);
FundCompany dapeng = new FundCompany(zhongxin);
People xiaoming = new People(zhongxin);
zhongxin.finishReport();
}
}
图 执行结果
2.3 优缺点
优点: 1)解除耦合,让双方都依赖 抽象,而不是具体;
缺点: 1)包含多个观察者时,开发会比较复杂,而且Java默认是顺序执行,一个观察者卡顿会影响整体执行效率,在 这种情况下,一般采用异步处理的方式;