在軟件開發中,很大部分時候就是操作數據,而不同數據下展示的結果我們將其抽象出來稱為狀態,我們平時開發時本質上就是對應用程序的各種狀態進行切換並作出相應處理。狀態模式就是一種適合多種狀態場景下的設計模式。使用狀態模式可以可以讓代碼更加清晰,提高應用程序的維護性和擴展性。
基礎知識
狀態模式定義一個對象,這個對象可以通過管理其狀態從而使得應用程序作出相應的變化。狀態模式是一個非常常用的設計模式,它主要有兩個角色組成:
(1)環境類:擁有一個狀態成員,可以修改其狀態並作出相應反應。
(2)狀態類:表示一種狀態,包含其相應的處理方法
狀態模式的實現
基本示例
我們簡單地通過一個紅綠燈的例子來說明狀態模式,紅綠燈擁有一個狀態:哪一種顏色的燈亮了,每一種顏色的燈亮了之后又各自的動作,一共有紅綠黃三種顏色的燈,也就是有三種狀態。
首先,需要一個最基本的紅綠燈對象,我們定義如下:
1 var trafficLight = (function () { 2 var currentLight = null; 3 return { 4 change: function (light) { 5 currentLight = light; 6 currentLight.go(); 7 } 8 } 9 })();
上面的代碼中,trafficLight是一個紅綠燈對象,它有一個局部變量currentLight表示當前亮燈的對象,同時返回一個方法,這個方法用來改變紅綠燈的狀態,並觸發相應的處理程序。
接着我們定義三種不同顏色的燈,代碼如下:
1 function RedLight() { } 2 RedLight.prototype.go = function () { 3 console.log("this is red light"); 4 } 5 function GreenLight() { } 6 GreenLight.prototype.go = function () { 7 console.log("this is green light"); 8 } 9 function YellowLight() { } 10 YellowLight.prototype.go = function () { 11 console.log("this is yellow light"); 12 }
這段代碼分別定義了紅綠黃三種顏色的燈對象,每一個對象都包含一個go方法作為亮燈之后的處理程序。
接着,我們在客戶端進行切換不同顏色的燈:
1 trafficLight.change(new RedLight()); 2 trafficLight.change(new YellowLight());
通過傳入燈對象到change方法中,從而改變紅綠燈的狀態,觸發其相應的處理程序,這就是一個典型的狀態模式的應用。
JS組件開發中的狀態模式
狀態模式在開發JS組件時非常有用,我們平時開發組件時很多時候要切換組件的狀態,每種狀態有不同的處理方式,這個時候就可以使用狀態模式進行開發
比如我們要開發一個菜單組件,菜單擁有最基本的兩種狀態:顯示和隱藏,相應的顯示或隱藏可能會有各自的其他操作。使用狀態模式的話,我們首先定義一個環境類,在這里也就是菜單對象,簡單地定義如下:
1 function Menu() { } 2 Menu.prototype.toggle = function (state) { 3 state(); 4 }
這個菜單類有一個toggle方法用來切換狀態,然后調用相應的處理方法。
接着我們定義兩種狀態,定義如下:
1 var menuStates = { 2 "show": function () { 3 console.log("the menu is showing"); 4 }, 5 "hide": function () { 6 console.log("the menu is hiding"); 7 } 8 };
在這里,通過一個對象menuStates來定義menu的狀態,這里有兩種狀態show和hide,然后擁有相應的處理方法。在使用的時候通過下面的方法進行調用:
1 var menu = new Menu(); 2 menu.toggle(menuStates.show); 3 menu.toggle(menuStates.hide);
這段代碼實例化了一個Menu對象,然后分別切換了顯示和隱藏兩種狀態,如果有第三種狀態,我們只需要menuStates添加相應的狀態和處理程序即可。
總結
狀態模式在開發Web組件時非常有用,能讓我們的代碼結構更加清晰,能夠很方便的增加組件的各種狀態。使用狀態模式的關鍵是要理清組件的各種狀態,搞清楚組件的不同狀態和相應的處理函數,對組件后期的維護和擴展有極大的好處。
