欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

學習JavaScript設計模式之狀態(tài)模式

 更新時間:2016年01月08日 17:08:14   作者:奮飛  
這篇文章主要為大家介紹了JavaScript設計模式中的狀態(tài)模式,對JavaScript設計模式感興趣的小伙伴們可以參考一下

狀態(tài)模式的關鍵是區(qū)分事物內部的狀態(tài),事物內部狀態(tài)的改變往往會帶來事物的行為改變。

當電燈開著,此時按下開關,電燈會切換到關閉狀態(tài);再按一次開關,電燈又將被打開。同一個開關在不同的狀態(tài)下,表現(xiàn)出來的行為是不一樣的。

一、有限狀態(tài)機

  • 狀態(tài)總數(shù)(state)是有限的。
  • 任一時刻,只處在一種狀態(tài)之中。
  • 某種條件下,會從一種狀態(tài)轉變(transition)到另一種狀態(tài)。

允許一個對象在其內部狀態(tài)改變時改變它的行為,對象看起來似乎修改了它的類。
解釋:
(1)將狀態(tài)封裝成獨立的類,并將請求委托給當前的狀態(tài)對象,當對象的內部狀態(tài)發(fā)生改變時,會帶來不同的行為變化。
(2)使用的對象,在不同的狀態(tài)下具有截然不同的行為(委托效果)

談到封裝,一般優(yōu)先考慮封裝對象的行為,而不是對象的狀態(tài)。
但在狀態(tài)模式中剛好相反,狀態(tài)模式的關鍵是把事物的每種狀態(tài)都封裝成單獨的類。

二、示例

點燈程序 (弱光 –> 強光 –> 關燈)循環(huán)

// 關燈
var OffLightState = function(light) {
  this.light = light;
};
// 弱光
var OffLightState = function(light) {
  this.light = light;
};
// 強光
var StrongLightState = function(light) {
  this.light = light;
};

var Light = function(){
  /* 開關狀態(tài) */
  this.offLight = new OffLightState(this);
  this.weakLight = new WeakLightState(this);
  this.strongLight = 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.currentState = this.offLight;
  this.button.click = function() {
    self.currentState.buttonWasPressed();
  }
};
// 讓抽象父類的抽象方法直接拋出一個異常(避免狀態(tài)子類未實現(xiàn)buttonWasPressed方法)
Light.prototype.buttonWasPressed = function() {
  throw new Error("父類的buttonWasPressed方法必須被重寫");
};
Light.prototype.setState = function(newState) {
  this.currentState = newState;
};

/* 關燈 */
OffLightState.prototype = new Light(); // 繼承抽象類
OffLightState.prototype.buttonWasPressed = function() {
  console.log("關燈!");
  this.light.setState(this.light.weakLight);
}
/* 弱光 */
WeakLightState.prototype = new Light();
WeakLightState.prototype.buttonWasPressed = function() {
  console.log("弱光!");
  this.light.setState(this.light.strongLight);
};
/* 強光 */
StrongLightState.prototype = new Light();
StrongLightState.prototype.buttonWasPressed = function() {
  console.log("強光!");
  this.light.setState(this.light.offLight);
};

PS:說明補充
必須把OffLightState、WeakLightState、StrongLightState構造函數(shù)提前。

new A("a");
var A = function(a) {
  console.log(a)
}

new B("b");
function B(b) {
  console.log(b);
}

函數(shù)聲明會被提升到普通變量之前。

三、性能優(yōu)化點

(1)如何管理狀態(tài)對象的創(chuàng)建和銷毀?
第一種僅當state對象被需要時才創(chuàng)建并隨后銷毀(state對象比較龐大,優(yōu)先選擇),
另一種是一開始就創(chuàng)建好所有的狀態(tài)對象,并且始終不銷毀它們(狀態(tài)改變頻繁)。
(2)利用享元模式共享一個state對象。

四、JavaScript版本的狀態(tài)機

(1)通過Function.prototype.call方法直接把請求委托給某個字面量對象來執(zhí)行

// 狀態(tài)機
var FSM = {
  off: {
    buttonWasPressed: function() {
      console.log("關燈");
      this.button.innerHTML = "下一次按我是開燈";   // 這是Light上的屬性!?。?
      this.currState = FSM.on;            // 這是Light上的屬性?。?!
    }
  },
  on: {
    buttonWasPressed: function() {
      console.log("開燈");
      this.button.innerHTML = "下一次按我是關燈";
      this.currState = FSM.off;
    }
  },
};

var Light = function() {
  this.currState = FSM.off;  // 設置當前狀態(tài)
  this.button = null;
};

Light.prototype.init = function() {
  var button = document.createElement("button");
  self = this;

  button.innerHTML = "已關燈";
  this.button = document.body.appendChild(button);
  this.button.onclick = function() {
    // 請求委托給FSM狀態(tài)機
    self.currState.buttonWasPressed.call(self);
  }

}

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

(2)利用delegate函數(shù)

var delegate = function(client, delegation) {
  return {
    buttonWasPressed: function() {
      return delegation.buttonWasPressed.apply(client, arguments);
    }
  };
};

// 狀態(tài)機
var FSM = {
  off: {
    buttonWasPressed: function() {
      console.log("關燈");
      this.button.innerHTML = "下一次按我是開燈";
      this.currState = this.onState;
    }
  },
  on: {
    buttonWasPressed: function() {
      console.log("開燈");
      this.button.innerHTML = "下一次按我是關燈";
      this.currState = this.offState;
    }
  },
};

var Light = function() {
  this.offState = delegate(this, FSM.off);
  this.onState = delegate(this, FSM.on);
  this.currState = this.offState; // 設置當前狀態(tài)
  this.button = null;
};

Light.prototype.init = function() {
  var button = document.createElement("button");
  self = this;

  button.innerHTML = "已關燈";
  this.button = document.body.appendChild(button);
  this.button.onclick = function() {
    // 請求委托給FSM狀態(tài)機
    self.currState.buttonWasPressed();
  }
}

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

希望本文所述對大家學習javascript程序設計有所幫助。

相關文章

最新評論