二、14【设计模式】之观察者模式

今天的博客主题

       设计模式 ——》 设计模式之观察者模式


观察者模式 OP (Observer Pattern)

 

定义

定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者都会收到通知并更新。

其核心是将观察者与被观察者解耦,以类似于消息广播发送机制联动两者,使被观察者的变动能通知感兴趣的观察者们,从而做出响应。

观察者模式也被称为:发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

 

应用场景

1)当更改一个对象的状态可能需要更改其他对象,并且实际的对象集事先未知或动态更改时。

2)实现类似广播机制,无需知道具体接收者,只需要发送广播,感兴趣的对象自动接收广播

3)

生活中的场景也很多,比如闹钟的设置,APP角标通知,邮件通知,广播通知,桌面程序的事件响应

 

优点

1)符合开闭原则

2)可在运行时建立对象之间的关系

3)实现了一对多的通讯机制,支持事件注册机制,支持兴趣分发机制,当被观察者触发事件时,只有感兴趣的观察者接收到通知。

4)

 

缺点

1)观察者数量过多,事件通知耗时比较长。

2)事件通知呈线性,如果其中一个观察者事件处理失败,则影响后续的观察者接收事件。

3)如果观察者和被观察者之间存在循环依赖,则可能造成两者之间循环调用,导致系统崩溃。

4)

 

源码中的应用

JDK API:
java.util.Observable
Spring Api:
org.springframework.context.ApplicationListener

 

代码示例

观察者模式主要包含四种角色

目标/主题(Subject):也就是被观察的对象,定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,提供了增加/删除/通知观察者对象的方法。,可以是接口或抽象类,也可以是一个具体类。

具体目标/主题(ConcreteSubject):目标/主题的子类,包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知。同时还实现了在目标/主题类中定义的抽象业务逻辑方法(若有),如果不需要扩展目标类,该类可省略。(其主要就是一个具体被观察者,当状态发生变化时,会通知观察者对象)

抽象观察者(Observer):观察者将对观察目标的改变做出反应,定义了响应通知的更新方法。

具体观察者(ConcreteObserver):维护一个指向具体目标对象的引用,存储具体观察者的有关状态,这些状态要和具体目标的状态保持一致。实现了抽象观察者的更新方法。(就是得到状态改变的通知,自动做出响应)

按照所包含的角色,写出的观察者代码可能会是这样的

// 目标、主题类
abstract class Subject{
    // 定义一个观察者集合用于存储所有观察者对象
    protected ArrayList<Observer> Observers = new ArrayList<>();

    // 注册方法,往观察者集合增加一个观察者者
    public void addObserver(Observer observer){
        Observers.add(observer);
    }

    // 注销方法,在观察者集合删除一个观察者者
    public void removeObserver(Observer observer){
        Observers.remove(observer);
    }

    // 抽象方法,通知观察者
    public abstract void notifys();
}

// 具体目标类
class ConcreteSubject extends Subject{

    // 实现通知方法
    @Override
    public void notifys() {
        // 遍历观察者集合,调用每一个观察者的响应方法
        for (Object obs : Observers){
            ((Observer) obs).update();
        }
    }
}

// 抽象观察者
interface Observer{
    void update();
}

// 具体观察者1
class ConcreteObserver1 implements Observer{

    @Override
    public void update() {
        System.out.println("ConcreteObserver1 做出具体响应");
    }
}

// 具体观察者2
class ConcreteObserver2 implements Observer{

    @Override
    public void update() {
        System.out.println("ConcreteObserver2 做出具体响应");
    }
}

// 客户端调用
public class ObserverPattern {
    public static void main(String[] args) {
        // 定义主题目标
        Subject subject = new ConcreteSubject();

        // 定义观察者
        Observer o1 = new ConcreteObserver1();
        Observer o2 = new ConcreteObserver1();

        // 注册观察者
        subject.addObserver(o1);
        subject.addObserver(o2);

        subject.notifys();
    }
}

// 输出结果
ConcreteObserver1 做出具体响应
ConcreteObserver2 做出具体响应

但真正实现起来不用这么复杂,JDK为我们提供了API,还有Guava API 都能帮助我们轻松实现。

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值