Web前端之路让前端飞终端研发部

设计模式

2017-09-23  本文已影响28人  Dabao123

设计模式-策略模式

公司的年终奖是根据工资基数和绩效来发放的。例如绩效为S的员工有4倍工资。A的员工有3倍工资。B的员工有2倍工资。
基本设计:

function B(salary,level){
      if('S' === level){
            return 4*salary;
      }else if('A' === level){
            return 3*salary
      }else if('B' === level){
            return 2*salary
      }
}

缺点:不利于进一步去拓展功能,比较危险:把核心代码全部暴露在外面。
改进:

function PerS(salary){
        return 4*salary;
}
function perA(salary){
        return 3*salary;
}
function perB(salary){
        return 2*salary;
}
var Obj = {
      S : perS,
      A: perA,
      B:perB
}
function B(salary,level){
       return Obj[level](salary);
}

好处:函数可以重复使用。
算法的使用和算法的实现分开。

设计模式-装饰者模式

装饰模式,也可以称为包装器,就是对某个对象进行再加工、使之功能增强的一种做法。
先把自己保存一个备份,再改写自己。典型的例子jquery的ready函数。

function ready(func){
      var  _onload = typeof window.onload == "function" ? window.onload : function(){};
      window.onload = function(){
              _onload();
             func();
      }
}

将window.onload函数进行改写,先将原有的onload函数保存,然后再添加用户自定义的方法。

设计模式-单例模式

构造器只能创建一个对象。当你再次去创建时,它会把那个已经创建好对象返回给你。而不是去另一个新的对象。

function Single(name){
      this.name = name
}
Single.instance = null;
Single.get = function(name){
        if(!Single.instance){
                 Single.instance = new Single(name);
                 return  Single.instance
        }else{
                 return  Single.instance
        }
}
var s1 = Single.get('s1')
var s2 = Single.get('s2')
s1 === s2  //true

缺点:是必须要用get方法,如果是直接使用new就失去单例的特征。

var S = (function (){
     var  instance = null;
     function Single(name){
          if(instance){
                return  instance
          }  
          this.name = name;
          return instance = this;
     }
     return Single;
})()
var s1 = new S('s1');
var s2 = new S('s2');

设计模式-观察者模式

顾名思义,就是订阅某些功能,然后在适当的时机发布出来,也就是执行这些功能。
订阅,就是把几个函数推入数组中待用;
发布,就是把缓存在数组中的那一坨函数列队执行

var event = {
            eventList:{},
            listen:function(key,fn){
                if(!this.eventList[key]){
                  this.eventList[key] = [];
                }
                this.eventList[key].push(fn);
            },
            remove:function(key,fn){
                var fns = this.eventList[key];
                if(!fns){
                    return false;
                }
                if(!fn){
                    //如果没有回调,表示取消此key下所有方法
                    fns && (fns.length=0);//这是一种快速清空数组的方法哦!
                }else{
                    for(var i=0;i<fns.length;i++){
                    //遍历方法列表,剔除需要取消的方法
                    //要注意fns是引用型变量,实际是去除了this.eventList[key]下的方法。
                    if(fns[i] == fn){
                      fns.splice(i,1);
                      }
                    }
                }
            },
            //trigger('loginSucc',参数1,参数2)
            trigger:function(){
                //出列第一个数据:'loginSucc'
                var key = Array.prototype.shift.call(arguments);
                var fns = this.eventList[key];//拿到一组函数
                if(!fns || fns.length === 0){
                    //没有要执行的函数,就返回
                    return false;
                }
                for(var i=0;i<fns.length;i++){
                    //arguments已经出列了一个数据,目前全是参数列表了
                    fns[i].apply(this,arguments);
                }
            }
        };
        var installEvent = function(obj){
            for(var i in event){
             obj[i] = event[i];
            }
        }
        var login = {};
        installEvent(login);
        //显示头像
        function showAvatar(){
            console.log('显示用户头像');
        }
        //显示消息列表
        function showMessage(){
            console.log('显示消息列表');
        }
        //订阅
        login.listen('loginSuccess',showAvatar);
        login.listen('loginSuccess',showMessage);
        //发布
        login.trigger('loginSuccess');
        //取消订阅
        login.remove('loginSuccess',showAvatar);
        //再次发布
        login.trigger('loginSuccess');
上一篇下一篇

猜你喜欢

热点阅读