javaScript有趣的观察者模式

328 阅读3分钟

设计模式之观察者模式

在我们的代码构建中,会有许许多多的代码设计方案供我们选择,来实现一些便利的操作,比如策略模式结合事件委托可以让我们的代码逻辑与节点的耦合性降低、达到根据赋予节点不同标记来实现不同的功能,又好比工厂模式与获取的页面数据相结合,达到不同数据进行不同的逻辑处理的效果,接下来介绍一种就好像是 在js数据方法中定义事件的模式,观察者模式.........

现在我们有这样一个现象 , 有一个函数中的数据会与另几个函数产生联动,一旦这个函数中保存的数据进行了更改,这些方法就会去判断这个数据,然后决定是否执行(可以想想你暑假作业,老师突然说要翻倍 ε=ε=ε=(~ ̄▽ ̄)~)

如果平常遇到这一种多对一的数据判断形式,我们可能会在定义许多监测这个对象的方法,然后在方法内部进行数据判断,然后在修改数据的函数内部进行一个执行全部函数的方式,或者将判断写在修改这个数据的函数内部,然后执行各个方法

但是,按照以上的俩种方式来写的话,我们的代码不但耦合性非常的高,修改数据的函数代码也会显得非常冗余,完成后想要修改的话,可能也会比较麻烦 对于以上的一些状况,我们可以采用设计模式中的观察者模式来解决这些相关问题。

首先实现模式的基本思路,在构造函数对象上定义一个数组,来保存一些观察这个对象的对象想要触发方法 ,而原型中有俩个方法,一个用于遍历执行这些方法同时传入数据,另一个用于对被观察者对象中的 数组添加方法(观察者与被观察者对象的角色可以相互转换)

    function Hunter(self, static) {
        if (this instanceof Hunter) {
            this.self = self;
            this.list = [];
            this.static = static === false ? static : true;

        } else {
            return new Hunter(self, static)
        }
    }
    Hunter.prototype.publish = function (condition, fun) {
        console.log(this)
        var self = this.self,
            list = this.list,
            len = list.length - 1;
        fun && fun.apply(this);
        for (var i = 0; i <= len; i++) {
            list[i].call(this, condition, i);
        }
    }
    Hunter.prototype.subscribe = function (target, fn, massage) {
        var massage = massage === false ? massage : true,
            fun,
            self = this;
        !!massage && (fun = function (he) {
            self.static && (fn.my = self.self);
            he.static && (fn.he = he.self);
            return fn
        }(target));

        target.list.push(fun);
    }

以上代码是一个扩展过的观察者模式的对象实例,我们可以在函数创建的时候,传入对象或其他的数值,将数据存储入对象中self中,如果我们static中定义了为true,则将该对象的数据存入函数队列要执行的方法中,这样在函数内部就可以操作到这些保存数据,以下是一个初始化的实例

var a = Hunter({ el: document.querySelector(".a"), name: "a同学", lv: "100级" }),
 b = Hunter({ el: document.querySelector(".b"), name: "b同学", lv: "50级" })

我们可以通过调用subscribe来观察这个对象,一旦对象使用了publish,则会去调用这个保存的方法

 a.subscribe(w, fun() )
 w.publish("on");

这样的话就可以触发整个的事件队列,将这些方法去遍历执行