观察者模式

定义对象间的一对多依赖,当一个对象状态变化时,相关的依赖对象都得到通知并被自动更新。

别名:发布-订阅模式、模型-视图模式、源-监听器模式、从属者模式。

举一个观察者模式的例子:

在前端使用Vue写程序时,都对Vue的数据绑定表示肯定。
那么在日常开发过程中肯定存在一个对象绑定多个标签,然后当数据变化时对应着行为或者数据也都发生变化。

Vue只需要收集绑定了同一个数据的所有元素。然后我们通过维护这一个集合,当数据变化时,通过遍历进行处理,那么就可以实现多个标签上的数据渲染。

而观察者模式的原理就是这样,收集所有会被影响的对象,我们可以通过List或者Set等集合进行收集,数据变化时通过遍历集合然后通知每一个元素进行处理。


发布-订阅 模式也是这个道理

多个消息订阅者,然后一个消息发布者。
消息发布后,订阅者就会收到消息,进行相应的操作


核心代码

通过下面的代码会发现。不管是开始销售还是结束销售,都需要调用通知粉丝的功能
意味着观察者模式的作用就是,观察到某个状态/变化/功能完成后 通知所有观察者
而观察者需要有一个接收消息的功能(通常通过抽象/接口抽取)

抽象观察者–消息发布者

/**
 * 双向观察
 */
public class Observer extends AbstractObserver{

    //1、观察者的核心,收集所有观察者
    List<AbstractFans> fansList = new ArrayList<>();

    void startSell() {
        System.out.println("开始卖东西");
        notifyFans("通知粉丝...正在卖货");
    }
    void endSell() {
        System.out.println("结束买东西");
        notifyFans("通知粉丝...货买完了");
    }

    @Override
    void addFans(AbstractFans fans) {
        fansList.add(fans);
    }

    @Override
    void notifyFans(String msg) {
        //1、通知所有粉丝
        for (AbstractFans fans : fansList) {
            fans.acceptMsg(msg);
        }
    }
}

定义规范,添加粉丝,通知粉丝等功能

public abstract class AbstractObserver {

    //添加粉丝
    abstract void addFans(AbstractFans fans);

    //通知粉丝
    abstract void notifyFans(String msg);
}

抽象粉丝–消息订阅者

AbstractFans

public abstract class AbstractFans {

    List<AbstractObserver> observers;//双向观察

    abstract void acceptMsg(String msg);

    void follow(AbstractObserver observers){
        observers.addFans(this);
    }
    
}
public class HumanFans extends AbstractFans {
    @Override
    void acceptMsg(String msg) {
        System.out.println("发布消息:"+msg);
    }
}
public class RobotFans extends AbstractFans {
    @Override
    void acceptMsg(String msg) {
        System.out.println("接收消息...");
    }
}