前端讀者 | Javascript設計模式理論與實戰:狀態模式
本文來自 @狼狼的藍胖子;連結:http://luopq.com/2015/11/25/design-pattern-state/
在軟體開發中,很大部分時候就是操作資料,而不同資料下展示的結果我們將其抽象出來稱為狀態,我們平時開發時本質上就是對應用程式的各種狀態進行切換並作出相應處理。狀態模式就是一種適合多種狀態場景下的設計模式。使用狀態模式可以可以讓程式碼更加清晰,提高應用程式的維護性和擴充套件性。
基礎知識
狀態模式定義一個物件,這個物件可以通過管理其狀態從而使得應用程式作出相應的變化。狀態模式是一個非常常用的設計模式,它主要有兩個角色組成:
- 環境類:擁有一個狀態成員,可以修改其狀態並作出相應反應。
- 狀態類:表示一種狀態,包含其相應的處理方法
狀態模式的實現
基本示例
我們簡單地通過一個紅綠燈的例子來說明狀態模式,紅綠燈擁有一個狀態:哪一種顏色的燈亮了,每一種顏色的燈亮了之後又各自的動作,一共有紅綠黃三種顏色的燈,也就是有三種狀態。
首先,需要一個最基本的紅綠燈物件,我們定義如下:
var trafficLight = (function () { var currentLight = null; return { change: function (light) { currentLight = light; currentLight.go(); } } })();
上面的程式碼中,trafficLight是一個紅綠燈物件,它有一個區域性變數currentLight表示當前亮燈的物件,同時返回一個方法,這個方法用來改變紅綠燈的狀態,並觸發相應的處理程式。
接著我們定義三種不同顏色的燈,程式碼如下:
//紅燈 function RedLight() { } RedLight.prototype.go = function () { console.log("this is red light"); } //綠燈 function GreenLight() { } GreenLight.prototype.go = function () { console.log("this is green light"); } //黃燈 function YellowLight() { } YellowLight.prototype.go = function () { console.log("this is yellow light"); }
這段程式碼分別定義了紅綠黃三種顏色的燈物件,每一個物件都包含一個go方法作為亮燈之後的處理程式。
接著,我們在客戶端進行切換不同顏色的燈:
trafficLight.change(new RedLight());
trafficLight.change(new YellowLight());
通過傳入燈物件到change方法中,從而改變紅綠燈的狀態,觸發其相應的處理程式,這就是一個典型的狀態模式的應用。
JS元件開發中的狀態模式
狀態模式在開發JS元件時非常有用,我們平時開發元件時很多時候要切換元件的狀態,每種狀態有不同的處理方式,這個時候就可以使用狀態模式進行開發
比如我們要開發一個選單元件,選單擁有最基本的兩種狀態:顯示和隱藏,相應的顯示或隱藏可能會有各自的其他操作。使用狀態模式的話,我們首先定義一個環境類,在這裡也就是選單物件,簡單地定義如下:
function Menu() { }
Menu.prototype.toggle = function (state) {
state();
}
這個選單類有一個toggle方法用來切換狀態,然後呼叫相應的處理方法。
接著我們定義兩種狀態,定義如下:
var menuStates = {
"show": function () {
console.log("the menu is showing");
},
"hide": function () {
console.log("the menu is hiding");
}
};
在這裡,通過一個物件menuStates來定義menu的狀態,這裡有兩種狀態show和hide,然後擁有相應的處理方法。在使用的時候通過下面的方法進行呼叫:
var menu = new Menu();
menu.toggle(menuStates.show);
menu.toggle(menuStates.hide);
這段程式碼例項化了一個Menu物件,然後分別切換了顯示和隱藏兩種狀態,如果有第三種狀態,我們只需要menuStates新增相應的狀態和處理程式即可。
總結
狀態模式在開發Web元件時非常有用,能讓我們的程式碼結構更加清晰,能夠很方便的增加元件的各種狀態。使用狀態模式的關鍵是要理清元件的各種狀態,搞清楚元件的不同狀態和相應的處理函式,對元件後期的維護和擴充套件有極大的好處。