「手写设计模式」观察者模式

891 阅读2分钟

理解名词

创建型设计模式主要解决“对象的创建”问题;结构型设计模式主要解决“类或对象的组合或组装”问题;行为型设计模式主要解决的就是“类或对象之间的交互”问题。

观察者模式(Observer Design Pattern)是一种行为型设计模式,也被称为发布订阅模式(Publish-Subscribe Design Pattern)

  • 观察者模式中有两类对象,Observer观察者对象和Observable对象(被观察者),也有其他叫法以及变种,例如Subject-Observer、Publisher-Subscriber、Producer-Consumer、EventEmitter-EventListener、Dispatcher-Listener。
  • Observer-Observable是多对一的关系,Publisher-Subscriber、Producer-Consumer可以是多对多的关系
  • 观察者十分在意被观察者的行为,它们需要根据被观察者的行为作出相应的反应动作。 在GoF《设计模式》中定义如下

在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

作用

解耦观察者和被观察者代码,将耦合在一起的代码拆分成职责更单一的观察者类和被观察者类,让其满足开闭原则、高内聚松耦合等特性,以此来控制和应对代码的复杂性,提高代码的可扩展性。

适用场景

适用于存在观察者对象和被观察者对象的场景。例如:

  • 邮件订阅、RSS Feeds
  • 消息队列
  • 浏览器DOM事件监听与交互

代码示例

我们需要定义两种类,观察者类和被观察者类。

/**
* 被观察者接口
*/
public Interface Observable {
    // 添加观察者
    void register(Observer observer);
    
    // 移除观察者
    void remove(Observer observer);
    
    // 通知观察者
    void notify(Message msg);
}

/**
* 被观察者类
*/
public class ObservableClass implement Observable {
    private List<Observer> observers = new ArrayList<>();
    
    @Override
    public void register(Observer observer) {
        observers.add(observer);
    }
    
    @Override
    public void remove(Observer observer) {
        observers.remove(observer);
    }
    
    @Override
    public void notify(Message msg) {
        for(Observer observer: observers) {
            observer.update(msg);
        }
    }
}

观察者类

public interface Observer { 
    // 当被观察者更新时,执行处理逻辑
    void update(Message message);
}

public class ConcreteObserverOne implements Observer { 
    @Override 
    public void update(Message message) { 
        //TODO: 获取消息通知,执行自己的逻辑... 
        System.out.println("ConcreteObserverOne is notified."); 
    }
}

public class ConcreteObserverTwo implements Observer { 
    @Override
    public void update(Message message) { 
        //TODO: 获取消息通知,执行自己的逻辑... 
        System.out.println("ConcreteObserverTwo is notified."); 
    }
}

使用示例

public class Demo { 
    public static void main(String[] args) { 
        ObservableClass observable = new ObservableClass();
        observable.register(new ConcreteObserverOne()); 
        observable.register(new ConcreteObserverTwo()); 
        observable.notify(new Message()); 
    }
}

业界经典实现

  • Google Guava - EventBus