一呼百应:监听变化的观察者模式

欢迎关注微信公众号:互联网全栈架构

观察者(Observer)模式属于行为型设计模式,它通常包含观察目标和观察者两类对象,当观察目标的状态发生改变时,会通知到所有的观察者,观察者再进行相应的处理。它的定义如下:

fd36150e0691043d33fb3b27f59cec9c.png

在对象间定义一种一对多的依赖关系,当一个对象的状态发生了改变,所有依赖它的对象都被通知且会自动更新。

观察者模式主要包括以下几个角色:

主题(Subject):也被称为被观察者,它维护了一个观察者列表,并提供方法用于观察者的注册、移除,以及通知观察者。

抽象观察者(Observer):它定义了一个通知接口,在主题改变时调用。

具体主题(Concrete Subject):实现主题接口,维护自身状态,并在状态改变时通知观察者。

具体观察者(Concrete Observer):实现抽象观察者,在主题状态改变时执行相应的操作。

90e77a8ceafba02f096eda2939288005.png

观察者模式UML类图

设想有这么一个场景:在电商公司的订单管理系统中,如果订单已经支付,需要通知到物流系统和采购系统,物流系统需要进行发货操作,而采购系统则需要采购新的商品,在这个案例中,订单就是一个被观察者,如果它的状态发生了改变(已支付),则需要通知到物流系统和采购系统,这两个系统执行相应的操作以应对这种状态的改变。

首先定义一个观察者接口:

package com.sample.patterns.observer;
// 抽象观察者
public interface Observer {
    // 观察者所需要做的更新
    void update();
}

接下来是抽象主题,在我们的案例里,它是一个订单:

package com.sample.patterns.observer;
// 订单接口,它是被观察者
public interface Order {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObserver();
}

然后是抽象主题的具体实现,也就是客户订单,它会维护一个自身的订单状态和一个观察者列表,在状态发生改变时通知到所有的观察者:

package com.sample.patterns.observer;
import java.util.ArrayList;
import java.util.List;
// 具体的被观察者类
public class CustomerOrder implements Order{
    private List<Observer> list = new ArrayList();
    // 订单状态:0 未支付;1 已支付
    private int state = 0;
    public int getState() {
        return state;
    }
    public void setState(int state) {
        this.state = state;
        notifyObserver();
    }
    @Override
    public void registerObserver(Observer observer) {
        list.add(observer);
    }
    @Override
    public void removeObserver(Observer observer) {
        list.remove(observer);
    }
    // 通知所有的观察者
    @Override
    public void notifyObserver() {
        for(Observer observer:list){
            observer.update();
        }
    }
}

有两个观察者的具体实体,一个是物流系统,一个是采购系统:

package com.sample.patterns.observer;
// 观察者:物流系统
public class LogisticsObserver implements Observer{
    private int state;
    private CustomerOrder order;
    public LogisticsObserver(CustomerOrder order){
        this.order = order;
        this.order.registerObserver(this);
    }
    @Override
    public void update() {
        this.state = order.getState();
        System.out.println("Observer state updated to: " + this.state);
        // 如果状态变为已支付,则开始运输
        if(this.state==1){
            System.out.println("Begin to transport!");
        }
    }
}
package com.sample.patterns.observer;
// 观察者:采购系统
public class PurchaseObserver implements Observer{
    private int state;
    private CustomerOrder order;
    public PurchaseObserver(CustomerOrder order){
        this.order = order;
        this.order.registerObserver(this);
    }
    @Override
    public void update() {
        this.state = order.getState();
        System.out.println("Observer state updated to: " + this.state);
        // 如果状态变为已支付,则开始运输
        if(this.state==1){
            System.out.println("Begin to purchase!");
        }
    }
}

最后,我们写一个客户端类来进行测试,我们先创建一个客户订单,并且让两个观察者订阅这个客户订单,然后再改变这个订单的状态,可以看到,物流系统和采购系统在订单状态改变后,都进行了相应的操作处理。

package com.sample.patterns.observer;
// 测试客户端
public class Client {
    public static void main(String[] args) {
        CustomerOrder order = new CustomerOrder();
        LogisticsObserver logisticsObserver = new LogisticsObserver(order);
        PurchaseObserver purchaseObserver = new PurchaseObserver(order);

        order.setState(1);
    }
}

输出结果如下:

536ac3b66c0f89ab937dc3d10e6545bf.png

以上就是关于观察者模式的介绍,它使得观察者和被观察者松耦合,比较适用于一对多且状态需要同步更新的场景,如果需要新增观察者,只需要实现Observer接口并注册到Subject的列表中即可。

都看到这里了,请帮忙一键三连啊,也就是点击文末的在看、点赞、分享,这样会让我的文章让更多人看到,也会大大地激励我进行更多的输出,谢谢!

鸣谢:

https://refactoring.guru/design-patterns/observer

https://w3sdesign.com/GoF_Design_Patterns_Reference0100.pdf

推荐阅读:

手把手:Spring Cloud Alibaba项目搭建

春天的故事:Spring框架的入门级知识

责无旁贷:超酷的责任链模式

聚沙成塔:聊聊建造者模式

公司裁员,码农竟然成了“帮凶”?(剧情杜撰)

删除重复记录但保留其中一行数据的sql写法

一条sql搞定这个需求,面试官直呼内行

MySQL如何进行表之间的关联更新

高频面试题:多线程顺序打印ABC字符20次

一网打尽:MySQL索引失效的场景大搜罗

这个设计模式的用法,一般人我不告诉他

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值