前端開發(fā)中使用”有限狀態(tài)機(jī)“解決復(fù)雜的交互問題
前端開發(fā)是有邏輯的,這點(diǎn)毋庸置疑。程序員的思維邏輯賦予了代碼各種能力,但是前端開發(fā)中經(jīng)常面對的是用戶的操作。在一個比較復(fù)雜的頁面中(貌似現(xiàn)在也很少有簡單頁面了),用戶的操作是不可預(yù)見的,假如有很多按鈕,每個按鈕都會做一件自己***的事,如果上帝保佑所有的這些操作,這些事件都彼此沒有限制,而且結(jié)果互不影響,那沒有問題。但在開發(fā)中好像沒有這種好運(yùn)氣,所以經(jīng)常需要協(xié)調(diào)和平衡這些函數(shù)之間的執(zhí)行。
如果你使用的是純JS或者單獨(dú)僅有jQuery的情況下,遇到這種讓人焦頭爛額的情形會尤為明顯,前端MVC一定程度上隱藏了并處理了這些問題,但是也并不完全。這個時候你可能需要了解一下關(guān)于”有限狀態(tài)機(jī)“的概念,前端開發(fā)中這應(yīng)該是一個很有用的東西。
描述一下”有限狀態(tài)機(jī)“:
有限狀態(tài)自動機(jī),簡稱狀態(tài)機(jī),是表示有限個狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動作等行為的數(shù)學(xué)模型。
狀態(tài)總數(shù)(state)是有限的。
任一時刻,只會處于一種狀態(tài)中。
在某種條件下,會從一種狀態(tài)轉(zhuǎn)變到另一種狀態(tài)中。
在維基百科中稱:有限狀態(tài)機(jī)FSM是設(shè)計(jì)和實(shí)現(xiàn)事件驅(qū)動程序內(nèi)復(fù)雜行為組織原則的有力工具。
對于前端來說,尤其是Javascript編程時,這個模型的意義就在于可以將其套用在很多對象上。具體個例子,比如一個按鈕平時就是正常的按鈕,當(dāng)你點(diǎn)擊后變成一個input。當(dāng)然你可能會說這么簡單的功能,我直接用jQuery甚至不用都可以,操作DOM顯示和隱藏就好了。如果你還抱有這種天真的想法,我只能說你沒遇到過讓你痛不欲生的頁面。。。當(dāng)頁面復(fù)雜到一定程度,單純操作DOM去處理前端只會加快你瘋掉的進(jìn)程。
這里對于Button套用有限狀態(tài)機(jī)的模型,相當(dāng)btn對象只有兩個狀態(tài),顯示狀態(tài)和編輯狀態(tài)。看看代碼吧:
- var btn = {
- // 當(dāng)前狀態(tài)
- currentState: 'btn',
- // 綁定事件
- initialize: function() {
- var self = this;
- self.on("click", self.transition);
- },
- // 狀態(tài)轉(zhuǎn)換
- transition: function(event){
- switch(this.currentState) {
- case "btn":
- this.currentState = 'input';
- doSomething();
- break;
- case "input":
- this.currentState = 'btn';
- doSomething();
- break;
- default:
- console.log('Invalid State!');
- break;
- }
- }
- };
上面就是有限狀態(tài)機(jī)的寫法,邏輯和層次上確實(shí)清晰了,對于狀態(tài)越多的對象,就越適合這種寫法。
通過有限狀態(tài)機(jī)的這種模式,我認(rèn)為最重要的一點(diǎn)就是將用戶的操作行為,也就是組件的事件響應(yīng)(比如點(diǎn)擊)與組件的行為表現(xiàn)分離開來.在確切的說,通過建立一個有限狀態(tài)機(jī)的模型,我們完全不關(guān)心用戶的點(diǎn)擊行為具體做了什么,這時組件可能會有幾種狀態(tài)對應(yīng)不同的表現(xiàn)形式,而用戶觸發(fā)的事件僅僅是切換了模型的狀態(tài).至于每個狀態(tài)的具體表現(xiàn)和行為,我們完全可以單獨(dú)定義,也就說這時一種行為和響應(yīng)上的解耦.
Github上有兩個比較好的庫,都是實(shí)現(xiàn)FSM的,有興趣可以具體看看:
https://github.com/fschaefer/Stately.js






























