《JS设计模式》读书笔记(六)

标签:JS 设计模式


读书笔记链接:

  • 《JS设计模式》读书笔记(一)
  • 《JS设计模式》读书笔记(二)
  • 《JS设计模式》读书笔记(三)
  • 《JS设计模式》读书笔记(四)
  • 《JS设计模式》读书笔记(五)
  • 《JS设计模式》读书笔记(七-完结)

享元模式

通过划分内部状态与外部状态来减少需要创建对象的数量,共享对象。与其他模式不一样的是,享元模式针对的是性能问题

区分内部状态与外部状态是使用享元模式的关键:

  1. 内部状态通常是可以被共享的属性,例如性别,岁数,等级之类可以划分出少数几个类别的属性。
  2. 外部状态就是各不相同的属性,例如大小,面积之类有很多个取值的属性。
  3. 其实内外状态的区分关键就是看该属性的取值哪个少。选最少哪个作为内部,其他外部。这样就使得共享的对象变到最少。
// 抽出内部属性以创建享元,这里内部属性是sex
// 享元模式也可以使用工厂模式来创建每个享元的单例。严格限定对象数量。
var Modal = function(sex) {
    this.sex = sex;
}
Modal.prototype.takePhoto = function(index){
    console.log('sex='+this.sex + '; cloth=' + this.clothes[index])
}
// 注意通常要用id++来记录每个享元的外部状态,这里是clothes
Modal.prototype.wear = function(clothes) {this.clothes = clothes};
var maleModal = new Modal('male')
maleModal.wear(['red','green','blue'])
var femaleModal = new Modal('female')
maleModal.wear(['dress','skirt','pants'])

// 这里只使用了两个对象就可以完成任务;其实也可以用cloth来做内部属性,不过有6个值,明显不如sex的两个值
for(var i=0,l=3;i

另外与一种享元模式有异曲同工之妙的技术是对象池技术,原理是使用缓存记录使用过的对象,调用时优先从缓存调用,调用后就放回缓存。

// objpool
var objectPoolFactory = function(createFn) {
    var pool = [];
    return {
        create: function(){
            return obj = pool.length === 0 ? createFn.apply(this, arguments) : pool.shift();
        },
        recover: function(obj) {
            pool.push(obj)
        }
    }
}

// example
var iframeFactory = objectPoolFactory(function(){
        var iframe = document.createElement('iframe');
        document.body.appendChild(iframe);
        iframe.onload = function(){
            iframe.onload = null; // 防iframe重复加载
            iframeFactory.recover(iframe);
        }
        return iframe;
    })
var iframe1 = iframeFactory.create();
iframe1.src = 'http://www.baidu.com';

setTimeout(function(){
    var iframe2 = iframeFactory.create(); // iframe1 === iframe2
    iframe2.src = 'http://www.qq.com'
}, 5000)


状态模式

使用状态机时,对每一个状态都独立封装成类(对象),各状态类复写同一个抽象方法,使用该方法来执行状态机。

不变:状态总要变化;状态的变换都是通过同一个方法;状态有各自的行为;
变化:状态类的细节;

结果:消除switch语句,不修改原有代码的情况下新增状态

// 状态模式结合有限状态机,开灯例子
var Light = function() {
    // 初始状态
    // 使用FSM来记录状态对象
    this.currState = FSM.off; 
    this.button = null;
}
Light.prototype.init = function(){
    this.button = document.createElement('button');
    this.button.innerHTML = 'off';
    document.body.append(this.button);
    that = this;
    this.button.onclick = function(){
        that.currState.toggle.call(that);
    }
}
// 每个状态都是一个对象,包含自己要维护的属性与一个约定公开的API(这里是toggle)
var FSM = {
    off: {
        toggle: function(){
            console.log('turn off light')
            this.currState = FSM.on;  // 这里是关键,改变当前状态
        }
    },
    on: {
        toggle: function(){
            console.log('turn on light')
            this.currState = FSM.off;  // 这里是关键,改变当前状态
        }
    }
}

var light = new Light();
light.init();

你可能感兴趣的:(《JS设计模式》读书笔记(六))