国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

學(xué)習(xí)JavaScript設(shè)計模式之狀態(tài)模式

2024-05-06 16:27:29
字體:
供稿:網(wǎng)友
這篇文章主要為大家介紹了JavaScript設(shè)計模式中的狀態(tài)模式,對JavaScript設(shè)計模式感興趣的小伙伴們可以參考一下
 

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

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

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

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

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

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

二、示例

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

// 關(guā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(){  /* 開關(guān)狀態(tài) */  this.offLight = new OffLightState(this);  this.weakLight = new WeakLightState(this);  this.strongLight = new StrongLightState(this);  /* 快關(guān)按鈕 */  this.button = null;};Light.prototype.init = function() {  var button = document.createElement("button"),    self = this;  this.button = document.body.appendChild(button);  this.button.innerHTML = '開關(guān)';  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;};/* 關(guān)燈 */OffLightState.prototype = new Light(); // 繼承抽象類OffLightState.prototype.buttonWasPressed = function() {  console.log("關(guān)燈!");  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構(gòu)造函數(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("關(guān)燈");      this.button.innerHTML = "下一次按我是開燈";   // 這是Light上的屬性!??!      this.currState = FSM.on;            // 這是Light上的屬性!?。?   }  },  on: {    buttonWasPressed: function() {      console.log("開燈");      this.button.innerHTML = "下一次按我是關(guān)燈";      this.currState = FSM.off;    }  },};var Light = function() {  this.currState = FSM.off;  // 設(shè)置當前狀態(tài)  this.button = null;};Light.prototype.init = function() {  var button = document.createElement("button");  self = this;  button.innerHTML = "已關(guān)燈";  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("關(guān)燈");      this.button.innerHTML = "下一次按我是開燈";      this.currState = this.onState;    }  },  on: {    buttonWasPressed: function() {      console.log("開燈");      this.button.innerHTML = "下一次按我是關(guān)燈";      this.currState = this.offState;    }  },};var Light = function() {  this.offState = delegate(this, FSM.off);  this.onState = delegate(this, FSM.on);  this.currState = this.offState; // 設(shè)置當前狀態(tài)  this.button = null;};Light.prototype.init = function() {  var button = document.createElement("button");  self = this;  button.innerHTML = "已關(guān)燈";  this.button = document.body.appendChild(button);  this.button.onclick = function() {    // 請求委托給FSM狀態(tài)機    self.currState.buttonWasPressed();  }}var light = new Light();light.init();

希望本文所述對大家學(xué)習(xí)javascript程序設(shè)計有所幫助。



注:相關(guān)教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 阳山县| 德格县| 黔西| 峨眉山市| 玉田县| 西峡县| 牙克石市| 高尔夫| 和静县| 双柏县| 巫溪县| 清原| 永福县| 昌吉市| 南康市| 鹤峰县| 观塘区| 长垣县| 鹤庆县| 新郑市| 平江县| 涡阳县| 婺源县| 通化县| 新绛县| 新和县| 绥江县| 高要市| 肇源县| 华容县| 华亭县| 确山县| 布尔津县| 寻甸| 油尖旺区| 桐庐县| 溧水县| 南部县| 涟水县| 大姚县| 竹溪县|