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 + " 度");
    }
}
发布了321 篇原创文章 · 获赞 676 · 访问量 147万+

猜你喜欢

转载自blog.csdn.net/zongf0504/article/details/100103574
21.