常用js设计模式整理

在做canvas、webGL游戏时,很深切的感觉到,游戏编程玩的都是设计模式。架构没预先设计好,强耦合性代码在后期维护简直灾难。

大型单页应用里,复杂度上升到一定程度时,没有适当的设计模式进行降耦,后续的开发也难以下手。

而设计模式正是为了降耦而存在。

参考《javascript设计模式》——曾探

函数节流

var throttle = function(fn, interval){    var _self = fn,        timer,        firstTime = true;    return function(){        var args = arguments.            _me = this;        if( firstTime ){                _self.apply(_me, args);            return first            }            if(timer){            return false;        }        timer = setTimeout(function(){            clearTimeout(timer);            timer = null;            _self.apply(_me, args);        }, interval || 500);    }    }window.onresize = throttle(function){    console.log(1);}, 500);

分式函数

var timeChunk = function(arr, fn, count){    var obj, t;    var len = ary.length;    var start = function(){        for(var i = 0; i  {    createSingleCreateLayer();}

策略模式

定义:封装一系列算法,并使其可以相互替换

计算工资Demo:

var strategies = {    'S': function(salary){        return salary * 4;    },    'A': function(salary){        return salary * 3;    }}var calculateBonus = (level, salary) => {    return strategies[level](salary);}

表单添加多种校验规则:

/*--------------- Strategies --------------*/var strategies = {    isNotEmpth: (value, errorMsg) => {        if(value == ''){            return errorMsg;        }    },    minLength: (value, length,errorMsg) => {        if(value.length  {    this.cache = [];}Validator.prototype.add = (dom, rules) => {    var self = this;    for(var i = 0; rule; rule = rules[i++]){        ((rule) => {            var strategyAry = strategy.split(':');            var errorMsg = rule.errorMsg;            self.cache.push(function(){                var strategy = strategyAry.shift();                strategyAry.unshift(dom.value);                strategyAry.push(errorMsg);                return strategies[strategy].apply(dom, strategyAry);            });        })(rule);    }};Validator.prototype.start = () => {    for(var i = 0; validatorFunc; validatorFunc = this.cache[i++]){        var errorMsg = validatorFunc();        if( errorMsg ){            return errorMsg;        }    }}/*-------------- 客户端调用 ------------*/var registerForm = document.getElementById('registerForm');var validataFunc = () => {    var validator = new Validator();    validator.add(registorForm.username, [{        strategy: 'isNotEmpty',        errorMsg: '用户名不能为空'    },{        strategy: 'minLength',        errorMsg: ‘最下长度为6’    }]);    validator.add(registorForm.password, [{        strategy: 'minLength',        errorMsg: '最小长度'    }])    var errorMsg = validator.start();    return errorMsg;}registerForm.onsubmit = () => {    var errorMsg = validataFunc();    if(errorMsg){        alert(errorMsg);        return false;    }}

代理模式

为一个对象提供一个代用品或者占位符,以便控制它的访问

面向对象设计原则——单一职责原则。面向对象设计鼓励将行为分布到细粒度的对象之中。

大量计算时加入代理作为缓存,异步请求时同理可用缓存:

var mult = () => {    var a = 1;    for(var i = 0, l = arguments.length; i  {    var cache = {};    return () => {        var args = Array.prototype.join.call(arguments, ',');        if( args in cache ){            return cache[args];        }        return cache[args] = mult.apply(this, arguments);    }})();

高阶函数动态创建代理

var mult = () => {    var a = 1;    for(var i = 0, l = arguments.length; i  {    var a = 0;    for(var i = 0, l = arguments.length; i  {    var cache = {};    return () => {        var args = Array.prototype.join.call(arguments, ',');        if(args in cache){            return cache[args];        }        return cache[args] = fn.apply(this, arguments);    }}

迭代器模式

迭代器模式指提供一种方法顺序访问一个聚合对象的各个元素,又不暴露该对象的内部表示。

通用外部迭代器:

var Iterator = (obj) => {    var current = 0;    var next = () => {        ++current;    }    var isDone = () => {        return current >= obj.length;    }    var getCurrItem = () => {        return obj[current];    }    return {        next: next,        isDone: isDone,        getCurrItem: getCurrItem    }}

发布-订阅模式

var event = {    clientListh: [],    listen: function(key, fn){        if(!this.clientListh[key]){            this.clientList[key] = [];        }        this.clientList[key].push(fn);    },    trigger: function(){        var key = Array.prototype.shift.call(arguments),            fns = this.clientList[key];        if(!fns || fns.length === 0){            return false;        }        for(var i = 0; fn; fn = fns[i++]){            fn.apply(this.arguments);        }    }}var installEvent = function(obj){    for(var i in event){        obj[i] = event[i];    }};var salesOffices = {};installEvnet(salesOffices);salesOffices.listen('squareMeter88', function(price){    console.log('price': + price);})salesOfffices.trigger('squareMeter88', 20000);

发布——订阅模式可以很大程度降低耦合性,但滥用也会造成背后逻辑混乱,且浪费内存。

命令模式

主要是回调函数的的面向对象的替代品

没看懂命令模式有什么意义

撤销和重做

var commandStack = [];document.onkeypress = (ev)=>{    var keyCode = ev.keyCode,        command = makeCommand(Ryu, commands[keyCode]);    if(command){        command();        commandStack.push(command);    }}$('# replay').onclick = ()=>{    var command;    while(command = commandStack.shift()){        command();    }}

宏命令

var closeDoorCommand = {    excute: ()=> {        console.lg('close door');    }}var openPcCommand = {    excute: ()=> {        console.log('open pc');    }}var MacroCommand = ()=> {    return {        conmandList: [],        add: (command)=>{            this.commandList.push(command);        },        execute: ()=>{            for(var i = 0, command; command = this.commandsList[i++]; ){                command.execute();            }        }    }}

组合模式

类似命令模式的加强版,也是看不懂深层意义

遍历文件夹

/       Folder         /var Folder = (name)=>{    this.name = name;    this.parent = null;    this.files = [];};Folder.prototype.add = (file)=> {    file.parent = this;    this.files.push(file);}Folder.prototype.scan = ()=>{    console.log('Begin scan: ' + this.name);    for(var i = 0, file = this.files; file = files[i++]; ){        file.scan();    }}Folder.prototype.remove = ()=>{    if(!this.parent){        return;    }    for(var files = this.parent.files, l = files.length-1; l >= 0; l--){        var file = files[l];        if(file === this){            files.splice(l, 1);        }    }}/       File         /var File = (name)=>{    this.name = name;    this.parent = null;}File.prototype.add = ()=>{    throw new Error('Can not add file under file');}File.prototype.scan = ()=>{    console.log('Begin Scan: ' + this.name);}File.prototype.remove = ()=>{    if(!this.parent){        return;    }    for(var files = this.parent.files, l = files.length-1; l >= 0; l--){        var file = files[l];        if(file == this);{            file.splice(l, 1);        }    }}

模板方法模式

基于继承的设计模式

模板方法模式友抽象父类和具体实现的子类组成。父类封装了子类的算法框架,子类通过集成抽象类,也继承了整个算法框架。

钩子方法

var Bevrage = function(){}Beverage.prototype.boilWater = function(){    console.log('把水煮沸');}Beverage.prototype.brew = function(){    throw new Error('Class brew musth be rewrited');}....Beverage.prototype.addCondiments = function(){    throw new Error('adCondiments must be rewrited');}Beverage.prototype.customerWantsCondiments = function(){    return true;}Beverage.prototype.init = function(){    this.boilWater();    this.brew();    ....    if(this.customerWantsCondiments()){        this.addCondiments();    }    }var CoffeeWithHook = function(){};CoffeeWithHook.prototype = new Beverage();CoffeeWithHook.prototype.brew = function(){    console.log('brew coffee with water');};CoffeeWithHook.prototype.customerWantsCondiments = function(){    return widow.confirm('需要调料嘛?');}var coffeeWithHook = new CoffeeWithHook();coffeeWithHook.init();

高阶函数可以更方便的实现上面的demo...

享元模式

用于性能优化,核心是运用共享技术来支持大量细粒度的对象。

通用对象池的实现

var objectPoolFactory = (createObjFn)=>{    var objectPool = [];    return{        create: function(){            var obj = objectPool.length === 0 ? createObjFn.apply(this, arguments) : objectPool.shift();            return obj;        },        recover: (obj){            objectPool.push(obj);        }    }}

职责链模式

用来重构代码挺方便的。

把不同功能函数包装成链式节点再调用。

var order500 = function(orderType, pay, stock){    if(orderType == 1 && pay == true){        conosle.log('500, 100优惠券')    } else{        return 'nextSuccessor'; // 把请求往后传递    }    }var order200 = function(orderTYPE, pay, stock){    if(orderType == 2 && pay ==true){        console.log('200, 50优惠券');    } else{        return 'nextSuccessor';    }}var orderNormal = function(orderType, pay, stock){    if(stock > 0){        console.log('普通购买,无优惠券');    } else{        console.log('库存不足');    }}//职责链包装函数//Chain.prototype.setNextSuccessor 指定在链中的下一个结点//Chain.prototype.passRequest 请求传递给某个结点var Chain = function(fn){    this.fn = fn;    this.successor = null;}Chain.prototype.setNextSuccessor = function(successor){    return this.successor = seccussor;}Chain.prototype.passRequest = function(){    var ret = this.fn.apply(this, arguments);    if(ret === 'nextSuccessor'){        return this.successor && this.seccessor.passRequest.apply(this.successor, arguments);    }    return ret;}//将订单函数包装进职责链var chainOrder500 = new Chain(order500);var chainOrder200 = new Chain(order200);var chainOrderNormal = new Chain(orderNormal);chainOrder500.setNextSuccessor(chainOrder200);ChainOrder200.setNextSuccessor(chainOrderNormal);//Test]chainOrder500.pasRequest(1, true, 500);

中介者模式

个人感觉有点像代理模式.用一个中介对象,来处理其他对象的时间,以实现解耦的目的。

但缺点也很明显,当系统复杂到一定程度时,中介者对象慢慢会变成一个难以维护的对象

装饰者模式

动态的给类添加职责

关键字:JavaScript, 设计模式, var, return


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部