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