昨天学习了第一篇的内容。。第二篇是关于对象创建的设计模式的。
第二篇 创建型设计模式
安全的工厂方法,如果想在其中添加其他类的时候,就可以在Factory这个工厂类的原型里写入方法就可以啦:
// 安全模式创建的工厂类 var Factory = function ( type , content ) { if ( this instanceof Factory) { var s = new this[type](content); return s; } else { return new Factory( type , content ); } }; // 工厂原型中设置创建所有类型数据对象的基类 Factory.prototype = { UI : function ( content ) { ( function ( content ) { var div = document.createElement('div'); div.innerHTML = content; div.style.border = '1px solid red'; document.getElementById('container').appendChild(div); } )( content ); } }; var data = [ {type: 'Javascript' , content: 'Javascript哪家强'}, {type: 'UI' , content: 'UI哪家强' } ]; var a = new Factory('UI','UI哪家强');
实测通过!耶!
接下来是建造者模式:将一个复杂对象的构建层与其表现层分离,同样的构建过程可采用不同的表示。
建造者模式更加的注重细节,而工厂模式得到的都是对象实例或者簇类。
// 创建一个人 var Human = function ( param ) { this.skill = param && param.skill || '保密'; this.hobby = param && param.hobby || '保密'; }; // 类人型方法 Human.prototype = function () { getSkill = function () { return this.skill; }; getHobby = function () { return this.hobby; }; }; // 实例化姓名类 var Name = function ( name ) { var that = this; ( function ( name , that ) { that.wholeName = name; if ( name.indexOf( ' ' ) > -1 ) { that.FirstName = name.slice( 0 , name.indexOf( ' ' ) ); that.SecondName = name.slice( name.indexOf( ' ' ) ); } } )( name , that ); }; // 实例化职位类 var Work = function ( work ) { var that = this; ( function ( that , work ) { switch( work ) { case 'code' : that.work = '工程师'; that.workDesc = '每天沉醉于编程'; break; case 'UI' : case 'UE' : that.work = '设计师'; that.workDesc = '每天沉醉于设计'; break; case 'teacher' : that.work = '老师'; that.workDesc = '每天沉醉于教学'; break; default : that.work = work; that.workDesc = '对不起,我们这里没有您职位的相关描述' } } )( that , work ); }; // 更换期望的职位 Work.prototype.changeWork = function ( work ) { this.work = work; }; // 添加职位描述 Work.prototype.changeDesc = function ( sentance ) { this.workDesc = sentance; }; /*========================= * 应聘者创建者 * 参数 name :姓名(全名) * 参数 work :期望职位 =========================*/ var Person = function ( name , work ) { var _person = new Human(); _person.name = new Name(name); _person.work = new Work(work); return _person; }; var person = new Person( 'yao ming' , 'code'); console.log ( person.skill ); // 保密 console.log ( person.work.work ); // 工程师 console.log ( person.work.workDesc ); // 每天沉醉于编程 person.work.changeDesc('更改一下职位描述!'); console.log ( person.work.workDesc ); // 更改一下职位描述
花了好长的时间写这个代码,然后思考了半天。。不是太明白,虽然看的懂。。但是让我写我还是不一定能写出来的。以后再回顾的时候好好的理一理,万事开头难不是吗?
接下来是原型模式:用原型实例指向创建对象的类,适用于创建新的对象的类共享原型对象的属性及方法。
// 图片轮播类 var LoopImages = function ( imgArr , container ) { this.imgArr = imgArr; this.container = container; }; LoopImages.prototype = { // 创建轮播图 createImage : function () { console.log ( 'LoopImages createImage function' ); }, // 切换下一张图片 changeImage : function () { console.log ( 'LoopImages changeImage function' ); } }; // 上下滑动切换类 var SlideLoopImg = function ( imgArr , container ) { LoopImages.call( this , imgArr , container ); }; SlideLoopImg.prototype = new LoopImages(); // 重写继承的切换下一张图片的方法 SlideLoopImg.prototype.changeImage = function () { console.log ( 'SlideLoopImg changeImage function' ); }; // 渐隐切换类 var FadeLoopImg = function ( imgArr , container , arrow ) { LoopImages.call( this , imgArr , container ); this.arrow = arrow; }; FadeLoopImg.prototype = new LoopImages(); FadeLoopImg.prototype.changeImage = function () { console.log ( 'FadeLoopImg changeImage function' ); }; var fadeImg = new FadeLoopImg( [ '01.jpg', '02.jpg', '03.jpg', '04.jpg' ] , 'slide' , [ 'left.jpg', 'right.jpg' ] ); // 测试用例 console.log ( fadeImg.container ); // slide fadeImg.changeImage(); // FadeLoopImg changeImage function
这个模式我喜欢~它可以在原型上做文章,可以很好的继承原型,方法上有冲突的时候而又可以修改自己的原型方法。精髓我感觉在于call改变了this的作用域,同时LoopImages这个函数可以获得很好的重用。
原型模式的对象复制,先写下来吧!怕以后忘了:
function prototypeExtend() { var F = function () {}, // 缓存类,为实例化返回对象临时创建 args = arguments, i = 0, len = args.length; for ( ; i < len ; i++ ) { for ( var j in args[i]) { // 遍历每个模板对象中的属性 F.prototype[j] = args[i][j]; // 将这些属性复制到缓存类原型中 } } return new F(); }
使用方式:
var penguin = prototypeExtend( { speed : 20, swim : function () { console.log ( '游泳速度' + this.speed ); }, run : function ( speed ) { console.log ( '奔跑速度' + speed ); }, jump : function () { console.log ( '跳跃动作' ); } } ); penguin.swim(); // 游泳速度20 penguin.run(10); // 奔跑速度10 penguin.jump(); // 跳跃动作
还有最后一个单例模式,头有点疼。。这些方法,我现在不太理解不知道怎么用,但是未来再回顾的时候,我慢慢的就理解了。
var Haoran = { id : function ( id ) { return document.getElementById( id ); }, css : function ( id , key , value ) { this.id( id ).style[ key ] = value; }, html : function ( id , value ) { this.id( id ).innerHTML = value; } }; Haoran.id( 'div1' );
以上就是所谓的单例模式啦,其实还是不难的嘛。使用这种模式可以封装自己的库,多棒啊!
var Haoran = { // 公共模块 Util : { util_Method1 : function () {}, util_Method2 : function () {} }, // 工具模块 Tool : { tool_1 : function () {}, tool_2 : function () {} }, // ajax模块 Ajax : { get : function () {}, set : function () {} }, // 其他模块 Others : { //... } }; Haoran.Util.util_Method1(); Haoran.Tool.tool_2();
就像这个样子!哈哈。。以后我也要封装自己的库,自己使用,也可以供大家使用。
惰性单例。。不知道啥东西?我能力还不够呀,先写这里吧:
var LazySingle = ( function () { // 单例引用 var _instance = null; // 单例 function Single() { return { // 这里定义私有属性和方法 publicMethod : function () {}, publicProperty : '1.0'; } } // 获取单例接口 return function () { // 如果为创建单例将创建单例 if ( ! _instance ) { _instance = Single(); } // 返回单例 return _instance; } } )();
接下来就是第三篇啦。。看的我还是有点稀里糊涂的。。不过我能感觉我在成长了!