《JavaScript设计模式》读书笔记——Day2

昨天学习了第一篇的内容。。第二篇是关于对象创建的设计模式的。

第二篇  创建型设计模式

安全的工厂方法,如果想在其中添加其他类的时候,就可以在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;
        }

    } )();

接下来就是第三篇啦。。看的我还是有点稀里糊涂的。。不过我能感觉我在成长了!

原文地址:https://www.cnblogs.com/luohaoran/p/5948794.html