极客学院 设计模式课程
设计模式存在的根本原因是为了代码复用,增加可维护性,有如下原则:
【开闭原则】对扩展开放,对修改关闭。
【里氏转换原则】子类继承父类,单独掉完全可以运行。
【依赖倒转原则】引用一个对象,如果这个对象有底层的类型,直接引用底层。
【接口隔离原则】每一个接口应该是一种角色。
【合成/聚合复用原则】新的对象应使用一些已有的对象,使之成为新对象一部分。
【迪米特原则】一个对象应对其他对象有尽可能少的了解。
单例模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 var xiaowang = (function (argument ) { var xiaowangjia = function (message ){ this .menling = message; } var men; var info = { sendMessage :function (message ) { if (!men){ men = new xiaowangjia (message); }; return men; } }; return info; })(); var xiaoli = { callXiaowang :function (msg ){ var _xxw = xiaowang.sendMessage (msg); alert (_xxw.menling ); _xxw = null ; } }; xiaoli.callXiaowang ('didi' ); xiaoli.callXiaowang ('hello' );
单例模式 按钮实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 var top = { init :function ( ){ this .render (); this .bind (); }, a :4 , render :function ( ){ var me = this ; me.btna = $('#a' ); }, bind :function ( ){ var me = this ; me.btna .click (function ( ){ me.test (); }); }, test :function ( ){ a = 5 ; } } var banner = { init :function ( ){ this .render (); this .bind (); }, a :4 , render :function ( ){ var me = this ; me.btna = $('#d' ); }, bind :function ( ){ var me = this ; me.btna .click (function ( ){ me.test (); }); }, test :function ( ){ top.a = 6 ; } } top.init (); banner.init ();
构造函数模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 function zaomen (huawen ){ var _huawen="普通" ; if (huawen){ _huawen = huawen; } this .suo = '普通' ; this .huawen = _huawen; this .create = function ( ){ return '【锁头】' + this .suo + '【花纹】' + this .huawen } } var xiaozhang = new zaomen (); alert ("xiaozhang" + xiaozhang.create ()); var xiaoli = new zaomen ('绚丽' ); alert ('xiaoli' + xiaoli.create ());
建造者模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 function Fangzi ( ){ this .woshi = "" ; this .keting = "" ; this .chufang = "" ; } function Baogongtou ( ){ this .gaifangzi = function (gongren ){ gongren.jian_woshi (); gongren.jian_keting (); gongren.jian_chufang (); } } function Gongren ( ){ this .jian_woshi = function ( ){ alert ("卧室盖好了" ); } this .jian_keting = function ( ){ alert ("客厅盖好了" ); } this .jian_chufang = function ( ){ alert ("厨房盖好了" ); } this .jiaogong = function ( ){ var _fangzi = new Fangzi (); _fangzi.woshi = "OK" ; _fangzi.keting = "OK" ; _fangzi.chufang = "OK" ; return _fangzi; } }; var gongren = new Gongren ;var baogongtou = new Baogongtou ();baogongtou.gaifangzi (gongren); var myfangzi = gongren.jiaogong ();console .log (myfangzi);
工厂模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 var gongchang = {};gongchang.chanyifu = function (argument ){ this .gongren = 50 ; alert ('我们有' + this .gongren + '个工人。' ) } gongchang.chanxie = function ( ){ alert ('生产鞋子' ); } gongchang.yunshu = function ( ){ alert ('运输' ); } gongchang.changzhang = function (para ){ return new gongchang[para](); } var me = gongchang.changzhang ('chanxie' );
代理模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 function maijia (argument ){ this .name = '小明' ; } function zhongjie ( ){} zhongjie.prototype .maifang = function ( ){ new fangdong (new maijia ()).maifang ("20万" ); }; function fangdong (maijia ){ this .maijia_name = maijia.name ; this .maifang = function (money ){ alert ('收到钱' ); } } var zhongjianshang = new zhongjie;zhongjianshang.maifang ();
司令模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 var lian = {}; lian.paobing = function (pao_num ){ alert (pao_num + '炮' + '开始战斗' ); } lian.bubing = function (bubing_num ){ alert (bubing_num + '人' + '开始战斗' ); } lian.lianzhang = function (mingling ){ lian[mingling.type ](mingling.num ); } lian.lianzhang ({ type :'paobing' , num :100 }); lian.lianzhang ({ type :'bubing' , num :500 })
极客学院-总结
极客学院的js设计模式教程的案例都是为了便于理解和解构出来的,但是我认为这样就是耍流氓,原理都懂但是没有实战就是纸上谈兵而已,所以我看完之后其实收获不大(能力有限(:з」∠) )
Chaining pattern 链式模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 var Calc = function (start ){ this .add = function (x ){ start = start + x; return this ; }; this .multiply = function (x ){ start = start * x; return this ; }; this .equals = function (callback ){ callback (start); return this ; }; } new Calc (0 ) .add (1 ) .add (2 ) .multiply (3 ) .equals (function (result ){ console .log (result); });
Creating Observerable Properties 观察者模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 var Book = function (name,price ){ var priceChanging = []; var priceChanged = []; this .name = function (val ){ return name; }; this .price = function (val ){ if (val !== undefined && val !== price){ for (var i = 0 ; i < priceChanging.length ;i++){ if (!priceChanging[i](val)){ return price; } } price = val; for (var i = 0 ; i < priceChanged.length ; i++){ priceChanged[i](this ); } } return price; }; this .onPriceChanging = function (callback ){ priceChanging.push (callback); }; this .onPriceChanged = function (callback ){ priceChanged.push (callback); }; } var book = new Book ('JavaScript: The Good Parts' ,23.99 );book.onPriceChanging (function (price ){ if (price > 100 ){ console .log ('系统错误,价格超过了预估值!' ); return false ; } return true ; }); book.onPriceChanged (function (b ){ console .log ('书本的价格已经改变为:¥' + b.price ()); }); book.price (19.99 ); book.price (20 );
JavaScript Design Patterns - 总结
观察者模式非常实用,可以在外部补充内部代码的不足,从外部完成对内部运行的一些代码补充,非常方便。 JQuery的链式模式我并没有怎么用,但是理论明白还是觉得非常方便的,threejs的add函数也是用相似的方法写的。
总结
设计模式其实所有面向对象语言都存在的,四人帮(gang of four)就有著名的著作 Jjs在设计模式的实现和其他语言大相径庭,因为js的理念是万物皆对象,无论是变量还是函数都可以升级为类,当然现在ES6标准已经加入了语法糖可以用类似Java的方法来构造类了。