您的位置:首页 > Web前端 > JavaScript

Javascript简单设计模式

2017-09-22 14:12 162 查看
1单例模式

之所以这样叫是因为它限制一个类只能有一个实例化对象。基本的实现方法是创建一个类,这个类包含一个方法,这个在没有对象的情况下,将会创建一个新的实例对象,如果存在实例对象,这个方法只返回这个对象的引用。但是Javascript本身是无类的。所以简单的说就是没有就创建,有就不创建直接使用。

例如:常用的点击按钮后出现一个遮罩层的需求。

var createMask = function(){

     return document.body.appendChild(document.createElement(div));

    }

    $('button').click(function(){

     var mask = createMask();

     mask.show();

})

上面的代码会出现一个问题,就是每次调用createMask都会创建一个新的div,虽然不需要的时候可以remove,或者隐藏掉,但还是会带来性能的损耗,可以做如下改进。

var mask = document.body.appendChild(document.createElement(‘div’));

$(‘button’).click(function(){

   mask.show()

  })

这样确实可以保证页面只会创建一个遮罩层,但是也有一个问题,就是如果用户不需要用到这个div,岂不是白白创建了它。于是我们可以借助一个变量来判断是否已经创建过div,代码如下

var mask;

var mask = function(){

  if(mask) return mask;

}else{

  mask = document.body.appendChild(document.createElement(‘div’));

  return mask;

}

这样看起来不错,但是mask作为一个全局变量,是否会造成污染呢?所以最好的办法如下:

var createMask = function(){

   var mask;

   return function(){

     Return mask || (mask = document.body.appendChild(document.createElement(‘div’)))    

  }

}()

这就是前面所说的“没有就创建,有就不创建直接用”。没错,单例模式就是这么简单。

2工厂模式

简单工程的特点就是参数化创建对象。简单工厂必须知道每一种产品以及何时提供给客户端。有人会说简单工厂添加新类的时候还是需要修改这部分代码,那么工厂模式的好处是什么呢?集中变化,创建的逻辑放在单一的位置,即使有变化,我们也只需要修改一处就好了。因此对系统要进行良好的分割,职责要清晰,毕竟简单工厂模式只是底层上的代码复用,以下是个简单的例子。

function A(){

this.getA = function(){

  console.log(‘a’);

 }

}

 

function B(){

  this.getB = function(){

  Console.log(‘b’);

 }

}

 

//创建工厂类

function Factory(){

  Return {

   create: function(type){

     var t;

     If(type ===’A’){

      t = new A();

   }else if(type === ‘B’){

      t= new B();

   }

   return t

  }

 }

}

//测试

var T = new Factory();

T.create(‘A’);

3观察者模式

观察者模式主要应用于对象之间一对多的依赖关系,当一个对象发生改变时,多个对该对象有依赖的其他对象也会跟着做出相应改变,这就非常适合用观察者模式来实现。使用观察者模式可以根据需要增加或删除对象,解决一对多对象间的耦合关系,使程序更易于扩展和维护。

观察者模式定义了对象间的一种一对多依赖关系,每当一个对象发生改变时,其相关依赖对象皆得到通知并被进行相应的改变。观察者模式又叫做发布-订阅模式。生活中有很多类似的关系,比如微信公众号订阅,多个读者订阅一个微信公众号,一旦公众号有更新,多个读者都会收到更新,而这种情况在应用程序中也非常常见,js绑定各种事件本质上就是观察者模式的实现。
观察者模式是一个非常有用的设计模式,它主要有两个角色组成:
(1)目标对象:作为一对多关系中的一,可以用来管理观察者的增加和删除
(2)观察者对象:观察目标对象,一旦目标发生改变则做出相应的反应

基本实例:

function Subject() {

    this.observers = [];

}

Subject.prototype = {

    constructor: Subject,

    subscribe: function (fn) {

        this.observers.push(fn);

        return this;

    },

    unsubscribe: function (fn) {

        this.observers = this.observers.filter(function (item) {

            if (item !== fn) {

                return item;

            }

        });

        return this;

    },

    fire: function (data, context) {

        this.observers.forEach(function (item) {

            item.call(context, data);

        });

        return this;

    }

};

目标对象Subject中有一个数组,这个数组保存观察者列表,而目标对象提供三个方法:观察对象,取消观察对象,触发对象更新。
我们通过subscribe方法增加观察者,保存到observers数组中,如果有需要可以通过unsubscribe方法取消订阅,然后更新数据时调用fire方法触发,从而通知各个观察者进行相应处理。

jQuery中实现观察者模式非常方便,简短的几句代码就可以实现

(function ($) {

            var obj = $({});

            $.subscribe = function () {

                obj.on.apply(obj, arguments);

            }

            $.unsubscribe = function () {

                obj.off.apply(obj, arguments);

            }

            $.fire = function () {

                obj.trigger.apply(obj, arguments);

            }

        })(jQuery);

在jQuery中,通过on方法来绑定事件,off来移除事件,trigger来触发事件,本质上就是一种观察者模式。上面代码中,我们通过一个obj对象来保存观察者对象,我们只要像平时绑定事件一样使用就可以,如下:

$.subscribe("render", function () {

    console.log("test");

})

$.subscribe("render", function () {

    console.log("test2");

})

$.fire("render");

这段代码分别输出test和test2.我们绑定了两个处理函数到render上,然后通过fire触发render事件,这就实现了观察者模式一对多依赖的特点。

4代理模式

代理模式使得代理对象控制具体对象的引用。代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西。

举个例子:

假如dudu要送酸奶小妹玫瑰花,却不知道她的联系方式或者不好意思,想委托大叔去送这些玫瑰,那大叔就是个代理(其实挺好的,可以扣几朵给媳妇),那我们如何来做呢?

var girl = function(name){

      this.name = name;

     }

 

     var dudu = function(girl){

      this.girl = girl;

      this.sendGift = function(gift){

      alert("Hi"+girl.name+" dudu送你,"+gift);

      }

     }

     var proxyTom = function(girl){

      this.girl = girl;

      this.sendGift = function(gift){

      (new dudu(girl)).sendGift(gift);

      }

     }

     var proxy = new proxyTom(new girl('大花'));

     proxy.sendGift("玫瑰");

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript 设计模式