告白-vue双向绑定(一)设计模式的理解

204 阅读5分钟

告白-vue双向绑定(一)设计模式 最近在看vue源码,它首要的一个特性就是双向绑定,那么它究竟是怎么实现的呢,在结合源码和网上的各种教程,我总结了一下,把自己的体会一一和大家分享开来。

我们首先谈谈它的设计模式是发布订阅模式,学习这个模式概念的时候我是吐血的,并且考虑了好久,才决心写下来我的感悟。

首先大家不要强行去记这个模式的没一个环节,因为设计模式只是用来描述特定场景下代码编写的一种方式。我们把有这个特点的编码方式称之为一种设计模式。

我们先介绍 观察者模式:

举一个例子,我在yy直播间关注了一个女主播,我就相当于订阅了女主播,当女主播有新的动态,她就会在自己的订阅列表里面把信息发送出去。这个模式中 我和 女主播 是相互知道的,我把我的 事件函数放在了女主播的订阅列表里面 我们直接形成了通信那么接下来我下用观察者这一模式来写下我这个例子

 // 定义一个yy,有 账号名 姓名等等吧,我们都可以在yy发布消息(release),订阅消息(subscribe)
    function yy(name, sex) {
        this.name = name; // 姓名
        this.sex = sex; // 性别
        this.list = [];
        return this;
    }
    /*订阅 :我们要 对订阅的 人做一个记录,例如谁订阅了 主播,这样 
    *主播在有发布时候就可以 把消息发布给订阅者了,因此可以把记录存到一个数组里面 
    */
    yy.prototype.subscribe = function (name, fn) {
        name.list.push(fn)
    }
    // 发布 :里面需要看看谁订阅了我。当我有消息时候就发布出去给订阅我的兄弟们。
    yy.prototype.release = function (msg) {
        this.list.map(item => {
            item(msg)
        })
    }
    // 首先我们初始化两个账号
    var linrufeng = new yy('林如风', '男') // 观察着
    var nvzhubo = new yy('小太阳', '女') // 被观察者
    /*
     *林如风 去订阅 一个女主播 ,当他开播时候 执行,送一朵玫瑰 == 当 有这个条件时我饿函数就触发了
     *注意 我们添加订阅  是在 nvzhubo 的 对象里面推送一个事件,所以接下来女主播的 对象list
     *中就有了我们 订阅 女主播 之后要做的事情队列啦
     *林如风 添加 女主播 == 我观察女主播 下面这个函数就实现了林如风对女主播的观察
    */
    linrufeng.subscribe(nvzhubo, function (msg) {
        console.log(msg+'送你一朵玫瑰,我叫林如风');
    });
    // 女主播发布消息 ,相当 于 我这个被订阅的对象 有事件触发,就把队列里面的事情 执行出来
    nvzhubo.release('马上就要开播啦,快来看我把');
    // subscribe release 有着严格的顺序 也就是说 要先 订阅了(对事件进行注册) 才能发布 (对事件进行触发)
    //这种模式呢,观察者和被观察者,存在交集  在这里subscribe(nvzhubo,fun)没有中介件
    

相信通过上面的解释大家应该立即观察者模式了。

**发布订阅模式:**它是观察者模式的一个别称,但是并不是观察者模式,他中间有一个(中间件),这就是他与观察者模式最大的不同。

我们接着上面的例子把故事说完。看一段这个女的,我发现这个女主播没啥意思了,我想看看有没有打游戏的主播,可是我不知道谁是打游戏的主播,于是我在 yy里面放了一个 我要订阅打游戏 这样一个情况, 当有一个主播,他打算直播打游戏了并且想通知所有订阅打游戏的人(此时他并不知道,谁订阅了要看打游戏的主播), 我和打游戏的主播都是通过 yy 这个平台统一管理的 ,yy就是中间件(事件函数管理中心)代码就是我把上面改了改,有些注释懒得改了。

   // 创建一个叫管理员的函数 它类似于我们的调度中心 和上文中一样有着发布订阅 的功能
        function margerYY(name) {
            this.name = name;
            this.tirgerObj = {};
            return this;
        }
        margerYY.prototype.subscribe = function (tirger, fn) {
            if (!this.tirgerObj[tirger]) {
                this.tirgerObj[tirger] = []
            }
            this.tirgerObj[tirger].push(fn)
        }
        margerYY.prototype.release = function (tirger, msg) {
            if (!this.tirgerObj[tirger]) {
                return;
            } else {
                this.tirgerObj[tirger].forEach((fn => {
                    fn(msg)
                }))
            }
        }
        // 创建一个yy管理中心
        var YYMarger = new margerYY('yy中间管理中心');
        // 一个yy号
        function yy(name, sex) {
            this.name = name; // 姓名
            this.sex = sex; // 性别
            return this;
        }
        //订阅 :我们要 对订阅的事件类型做一个记录
        yy.prototype.subscribe = function (tirger, fn) {
            YYMarger.subscribe(tirger, fn);
        }
        // 发布 :里面需要看看谁订阅了  我要发布的事件类型 如果有就通知他们
        yy.prototype.release = function (tirger, msg) {
            YYMarger.release(tirger, msg)
        }
        // 首先我们初始化两个账号
        var linrufeng = new yy('林如风', '男') // 观察着     
        var nvzhubo = new yy('小太阳', '女') // 被观察者

        // 林如风 去订阅 一个女主播 ,当他开播时候 执行,送一朵玫瑰 == 当 有这个条件时我饿函数就触发了
        /**
         *  注意 我们添加订阅  是在 nvzhubo 的 对象里面推送一个事件,所以接下来女主播的 对象list 中就有了我们 订阅 女主播 之后要做的事情队列啦
         * 
        */
        // 林如风 添加 女主播 == 我观察女主播 下面这个函数就实现了林如风对女主播的观察
        linrufeng.subscribe('game', function (msg) {
            console.log('打枪打枪' + msg);
        });
        // 女主播发布消息 ,相当 于 我这个被订阅的对象 有事件触发,就把队列里面的事情 执行出来
        nvzhubo.release('game', '马上就要开播啦,快来看我把');

整个过程, 我和女主播都不知道对方存在,但是 他发布的游戏主播成为了我的观察对象。

故事说完了,喜欢就就点赞吧。 喜欢不要错过下一篇开始双向绑定的告白。