09 状态,适配器

状态模式

  • 状态模式的关键是把事物的每种状态都封装成单独的类,跟此种状态有关的行为都被封装在这个类内部;当内部状态改变时,会带来不同的行为变化;

电灯开关的例子

var offLightState = function(light) {
  this.light = light;
};
offLightState.prototype.buttonWasPressed = function() {
  console.log('weakLightState');
  this.light.setState(this.light.weakLightState);
};
var weakLightState = function(light) {
  this.light = light;
};
weakLightState.prototype.buttonWasPressed = function() {
  console.log('strongLightState');
  this.light.setState(this.light.strongLightState);
};
var strongLightState = function(light) {
  this.light = light;
};
strongLightState.prototype.buttonWasPressed = function() {
  console.log('offLightState');
  this.light.setState(this.light.offLightState);
};

var Light = function() {
  this.offLightState = new offLightState(this);
  this.weakLightState = new weakLightState(this);
  this.strongLightState = new strongLightState(this);
  this.button = null;
};
Light.prototype.init = function() {
  var button = document.createElement('button');
  self = this;
  this.button = document.body.appendChild(button);
  this.button.innerHTML = '开关';
  this.currState = this.offLightState;
  this.button.onclick = function() {
    self.currState.buttonWasPressed();
  }
};
Light.prototype.setState = function(newState) {
  this.currState = newState;
};

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

JS版本的状态机器

  • JS是无类的,没有规定让状态对象一定要从类中创建而来;此外JS可以非常方便地使用委托技术,并不需要要事先让一个对象持有另一个对象;
var delegate = function(client, delegation) {
  return {
    buttonWasPressed: function() {
      return delegation.buttonWasPressed.apply(client, arguments);
    }
  }
};

var FSM = {
  off: {
    buttonWasPressed: function() {
      console.log('on');
      this.currState = this.onState;
    }
  },
  on: {
    buttonWasPressed: function() {
      console.log('off');
      this.currState = this.offState;
    }
  }
};

var Light = function() {
  this.offState = delegate(this, FSM.off);
  this.onState = delegate(this, FSM.on);
  this.button = null;
};
Light.prototype.init = function() {
  var button = document.createElement('button');
  self = this;
  this.button = document.body.appendChild(button);
  this.button.innerHTML = '开关';
  this.currState = this.offState;
  this.button.onclick = function() {
    self.currState.buttonWasPressed();
  }
};

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

另一个例子

var MarryState = function () {
  var _currentState = {};
  var states = {
    jump: function () {
      console.log('jump');
    },
    move: function () {
      console.log('move');
    },
    shoot: function () {
      console.log('shoot');
    },
    squat: function () {
      console.log('squat');
    }
  };
  var Action = {
    changeState: function () {
      var arg = arguments;
      _currentState = {};
      if(arg.length) {
        for(var i = 0, l = arg.length; i < l; i++) {
          _currentState[arg[i]] = true;
        }
      }
      return this;
    },
    gose: function () {
      console.log('gose');
      for(var i in _currentState) {
        states[i] && states[i]();
      }
      return this;
    }
  };
  return {
    change: Action.changeState,
    gose: Action.gose
  }
} 
var marry = new MarryState();
marry.change('jump', 'shoot').gose().gose()
  .change('shoot').gose();

状态模式和策略模式

  • 相同点是都有一个上下文,一些策略或者状态类,上下文吧请求委托给这些类来执行;
  • 区别是策略模式中各个策略类之间是平等又平行的,他们之间没有任何联系;客户必须熟知这些策略类的作用以便随时主动切换算法;
  • 状态模式中,状态和状态对应的行为是早已封装好的,之间的切换也是规定好的,改变行为发生在状态模式内部;客户并不需要了解这些细节;

对于分支优化

  • 工厂方法模式: 创建性模式,目的是创建对象;
  • 状态模式: 行为性模式,核心是对象状态的控制来决定表现行为,状态之间不能替换;
  • 策略模式: 行为性模式,核心是算法,由于每种算法处理的业务逻辑相同,可以互相替换;

适配器模式

  • 将一个类(对象)的接口转化为另一个接口,解决接口不匹配的问题;
  • 设计之初不会考虑,用于补救的模式;

适配异类框架

参数适配

function doSomeThing(obj) {
  var _adapter = {
    name: 'jinks',
    titile: 'enginner',
    age: 24,
    ....
  }
  for(var i in _adapter) {
    _adapter[i] = obj[i] || _adapter[i];
  }
  //doSome
}

数据适配

  • 将数组转化为易于理解的对象格式;
  • 服务器与客户端接口数据的适配;
posted @ 2015-10-19 23:38  JinksPeng  阅读(161)  评论(0编辑  收藏  举报