观察者设计模式解读

观察者模式是一个使用率非常高的模式,它常用的地方是GUI系统、订阅—-发布系统。因为这个模式的一个重要作用就是解耦,将被观察者和观察者解耦,使得它们之间的依赖性更小,甚至做到毫无依赖。

定义

定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。

UML图

Observer UML

  • Subject
    抽象主题,也就是被观察者(Observable)的角色,抽象主题角色把所有观察者对象的引用保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象
  • ConcreteSubject
    具体主题,该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发出通知,具体主题角色又叫具体被观察者(ConcreteObservable)角色
  • Observer
    抽象观察者,该角色是观察者的抽象类,它定义了一个更新接口,使得在得到主题的更改通知时更新自己
  • ConcreteObserver
    具体的观察者。该角色实现抽象观察者角色所定义的更新接口,以便在主题状态发生变化时更新自身的状态

观察者模式代码实现(Java)

抽象被观察者


public abstract class Subject {

    // 定义一个观察者数组
    private Vector<Observer> obs = new Vector<>();

    // 增加一个观察者
    public void addObserver(Observer o) {
        this.obs.add(o);
    }

    // 删除一个观察者
    public void delObserver(Observer o) {
        this.obs.remove(o);
    }

    // 通知所有观察者
    public void notifyObservers() {
        for (Observer o : this.obs) {
            o.update();
        }
    }

    public abstract void doSomeThing();

}

具体被观察者

public class ConcreteSubject extends Subject{
    
    

    @Override
    public void doSomeThing() {
        // TODO 被观察者 处理具体业务逻辑
        System.out.println("被观察者处理业务逻辑 ,并通知观察者");
        // 通知观察者 
        super.notifyObservers();
    }

}

观察者

public interface Observer {
    // 更新方法
    public void update();
}

具体观察者

public class ConcreteObserver implements Observer{
    
    
    @Override
    public void update() {
        // 观察者处理具体业务逻辑
        System.out.println("观察者接到信息,并处理");  
    }
}

观察者模式调用

public class ObserverPatterns {

    public static void main(String[] args) {
        ConcreteSubject observed = new ConcreteSubject();
        Observer observer=new ConcreteObserver();
        observed.addObserver(observer);
        observed.doSomeThing();
    }
}

适用场景

  1. 关联行为场景
  2. 事件多级出发场景
  3. 跨系统的消息交换场景,如消息队列、事件总线的处理机制

总结

观察者模式主要的作用就是对象解耦,将观察者与被观察者完全隔离,只依赖于Observer和Observable抽象

优点

  • 观察者和被观察者之间是抽象耦合,应对业务变化
  • 增强系统的灵活性、可拓展性

缺点

在应用观察者模式时需要考虑一下开发效率和运行效率问题,程序中包含一个被观察者,多个观察者、开发和调试等内容会比较复杂,而且在JAVA中消息的通知默认是顺序执行,一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般采用异步的方式

猜你喜欢

转载自blog.csdn.net/xufei5789651/article/details/79937870