观察者模式其实很简单

75 阅读2分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」


哈喽,大家好,我是一条。

今天想和大家聊一下观察者模式,在源码中经常看到,应用非常广泛,属于行为型设计模式。

还是老规则哈,准备一个maven 工程,并安装lombok依赖和插件。

定义

官方版

定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

说人话

其实观察者模式换成事件监听模式可能更好理解,比如我们需要监听一个按钮,当其发生单击事件,我们做出一个响应,当其发生双击事件,我们做出另一个响应。

总的来说,观察者模式只有两个角色,观察者和被观察者,或者叫监听器和事件源,为了可扩展我们会把这两个角色抽象出来。

Coding

情景再现

大家都知道一条是一个技术博主,偶尔会和大家直播互动,那我希望我的粉丝立马能收到我的开播通知,不会错过直播,那我就是一个被观察者,粉丝们就是很多个观察者。

下面就用代码模拟一下这个过程。

新建博主和粉丝类

public abstract class Bloggers {
    // 核心
    abstract void notifyFans(String msg);

    abstract void addFans(Fans fans);
}

public abstract class Fans {
    abstract void handlePublish(String msg);

    void followBlogger(Bloggers bloggers){
        bloggers.addFans(this);
    }
}

博主和粉丝的实现类

首先每个博主应该维护一个粉丝列表,通知遍历该列表,调用粉丝的接受消息方法。

public class YitiaoBlogger extends Bloggers{
   // 维护一个粉丝列表
    List<Fans> fans = new ArrayList<>();

    public void startLive(){
        System.out.println("startLive....");
        notifyFans("startLive");
    }

    public void endLive(){
        System.out.println("endLive....");
        notifyFans("endLive");
    }

    @Override
   // 通知粉丝
    public void notifyFans(String msg) {
        for (Fans fan : fans) {
            fan.handlePublish(msg);
        }
    }

    @Override
    public void addFans(Fans fans) {
       this.fans.add(fans);
    }
}
public class LiSiFan extends Fans{
    @Override
    void handlePublish(String msg) {
        System.out.println("LiSiFan receive:"+msg);
    }
}

public class ZhangSanFan extends Fans{
    @Override
    void handlePublish(String msg) {
        System.out.println("ZhangSanFan receive:"+msg);
    }
}

测试

  public class MainTest {
    public static void main(String[] args) {
        YitiaoBlogger yitiaoBlogger = new YitiaoBlogger();
        yitiaoBlogger.startLive();
        ZhangSanFan zhangSanFan = new ZhangSanFan();
        LiSiFan liSiFan = new LiSiFan();
        zhangSanFan.followBlogger(yitiaoBlogger);
        liSiFan.followBlogger(yitiaoBlogger);
        System.out.println("living。。。。");
        yitiaoBlogger.endLive();
    }
}  

输出

startLive....
living。。。。
endLive....
ZhangSanFan receive:endLive
LiSiFan receive:endLive

类图

源码

  • spring的时间监听机制
  • vue的Vue的双向绑定
  • 响应式编程