设计模式
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');