21. 23种经典设计模式-34-观察者模式扩展

本文探讨了标准观察者模式的问题,并提出了一种改进方案。通过解耦观察者与被观察者,使观察者能直接接收变化内容,避免了多线程下状态不一致的问题。介绍了扩展模式的类图,包括抽象接口、具体被观察者、观察者及其实现。

1. 观察者模式扩展

笔者上篇博客中提到, 对于四人帮定义的标准观察者模式而言, 有两个问题:

  • 观察者中需要持有具体观察者的引用,这样导致观察者与被观察者直接有强耦合关系
  • 观察者更新方法需要调用被观察者的方法获取实时状态, 虽然这种是为了保证消息通知时最小量化消息的设计,但是在多线程时,我们可能那不到实际触发变更时的状态。因此我们可以此进行改进,观察者的更新方法接收一个参数,接收变化的内容.

1.1 扩展模式-类图

根据上述问题, 笔者将标准观察者模式做以下改动:

  • 抽象被观察者模式升级为接口, 保证更通用更灵活
  • 具体观察者模式需要实现观察者的管理和通知逻辑,也可在此之间增加一层抽象.
  • 观察者角色的更新方法新增参数, 用于传入触发通知方法时的因素
  • 具体观察者中不再和被观察者耦合,不再持有对被观察者的引用,更新方法也无须再查询状态.

1.2 被观察者模式-抽象接口

将被观察者模式抽象为接口,对观察者的管理下沉到具体子类.

public interface ISubject {

    public void attach(Observer observer);

    public void detach(Observer observer);

    public void notifyObservers(Object object);
}

1.3 具体被观察者-TemperatureSubject

需要自己实现观察者的管理和通知方法.


public class TemperatureSubject implements ISubject {

    // 存储观察者列表
    private LinkedList<Observer> observers = new LinkedList<>();

    // 保存当前温度
    private String temperature;

    public void setTemperature(String temperature) {
        this.temperature = temperature;

        System.out.println("更新当前温度为:" + temperature + " 度");

        // 通知观察者
        this.notifyObservers(temperature);
    }

    public String getTemperature() {
        return this.temperature;
    }

    @Override
    public void attach(Observer observer) {
        this.observers.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        this.observers.remove(observer);
    }

    @Override
    public void notifyObservers(Object object) {
        this.observers.forEach(observer -> observer.update(object));
    }
}

1.4 观察者-Observer

public interface Observer {

    // 更新方法: 接收到通知后, 进行更新操作
    public void update(Object object);
}

1.5 web观察者-WebObserver

更新方法直接接收到变更的消息,无须再次查询.

public class WebObserver implements Observer {

    @Override
    public void update(Object temperature) {
        System.out.println("Web-接收到消息, 当前温度是:" + temperature + " 度");
    }
}

1.6 app观察者-AppObserver

更新方法直接接收到变更的消息,无须再次查询.

public class AppObserver implements Observer {

    @Override
    public void update(Object temperature) {
        System.out.println("App-接收到消息, 当前温度是:" + temperature + " 度");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值