? ? ? ? js的設計模式兩年前就開始接觸了,起初只是跟著張容銘小哥的《JavaScript設計模式》學學js的面向對象,閉包的使用,繼承封裝這些基礎。
? ? ? ? 剛開始學設計模式的時候總覺得項目中用不上啊,我直接if else for循環個好幾遍寫好邏輯就好了呀。然而當我成為一名在互聯網公司混跡多年的老菜鳥,我發現同樣是一段業務,有的人就能把它寫成詩,有些人就會把它寫成屎。
? ? ? ? 說的有點多了,還是回到主題吧,這一篇好好分享一下我對狀態模式的理解。
? ? ? ? 我對他的第一感覺是,當一個對象內充滿了對各種不同狀態而做出的不同邏輯變化,避免堆砌邏輯判斷,說的直接點就是少寫if else。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ——高級裝逼工程師Yubble
? ? ? ? 書中給到的實例是這樣的:
? ? ? ? 可以看到這就是在下還是一只小菜雞時候的編碼風格,當我的狀態碼越來越多,我這個ShowResult方法會越來越長,照這個路子寫我else if就得這么一直加下去。我的業務倒也沒什么毛病,功能也能實現,照樣兒跟老板交差領工資。
? ? ? ? 但是!如果等到這個項目業務夠大了。ShowResult這個方法變得特別龐大,其中光一個else if (result == 1) {} 的代碼塊就十好幾行,這個時候我們增刪改查一塊狀態邏輯的成本可就上去了,這個時候如果項目中來個新同學絕對看哭啊。
? ? ? ? 所以書中給到的解決方案是這樣的:
? ? ? ? 作者用了個自執行的函數做了個閉包,返回了一個對象,這個對象有一個show方法...算了太簡單了,自行體會吧~
? ? ? ? 但是有一個地方在下一定要多嘴一句,很多客爺分不清狀態模式和策略模式,因為這兩種設計模式都是在減少if else的編寫量,可以說核心思想是一致的。不過如果要仔細分辨還是有幾點區別的,不過在下這節不講~??????????
? ? ? ? 不過狀態模式的特點還是一定要提:
? ? ? ? ? ? 1,一定存在狀態對象和環境方法
? ? ? ? ? ? 2,是針對一個對象的狀態做的方法處理,所以方法只對當前對象有用,不可復用
? ? ? 雖說是我這個老菜雞自己意會總結的兩點,但還是經過我一次次與面試官吹牛逼的淬煉過的。
? ? ? 我們還是結合上面這個例子來做個深入理解吧。
? ? ? ? 首先這部分就是我們保存的狀態對象,如果在實際項目中可以把它單獨寫在一個js文件中,是不是形成分離了。
? ? ? ? 光有狀態我們也要有方法去調用啊,這就是調用不同狀態的環境方法。
? ? ? ? 不論哪個使用狀態模式的對象,其內部一定至少包含這兩個部分。? ? ? ?
? ? ? ? 然后就是它的調用,因為這種設計模式對應解決的業務核心還是對象的狀態,所以他也只是給對象自己用的,無法復用。
? ? ? ? 在網上呢看到了一些實例,但是不論哪些都離不開狀態與環境這兩大特點。
? ? ? ? 讓我們通過兩個可愛的習題來鞏固一下設計思維吧~
? ? ? ? 首先是經典的紅綠燈案例。
? ? ? ? 我的菜雞思維:
? ? ? ? 首先這么寫肯定也沒錯,項目中這么用也沒有毛病,但是我就是固執的想嘚瑟一下~
? ? ? ? 上面這個紅綠燈實例我把燈的三種狀態單獨提了出來作為status對象,將調用狀態的環境方法寫成了change方法,這樣一個健康的狀態模式思維算是出現了,但是如果真的是項目中某一個對象只有三種狀態,其實沒必要弄這么嘚瑟一下,工作中還是低調一點比較好...
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ———————————手動分割線———————————
? ? ? ? 其次是《JS設計模式》中提到的超級瑪麗
? ? ? ? 這個案例在小可腦中可以說是刻畫的入木三分,因為它也是解決了在下一段時間寫h5活動頁時混亂的思路和方式。
? ? ? ? 當我們玩超級瑪麗時控制的瑪麗就是一個對象,如果客爺是游戲圈的應該是叫一個精靈對吧,那么我們可以通過控制瑪麗的各種‘狀態’:跑,跳,蹲,來過關游戲。
? ? ? ? 身為菜雞的我就會這么寫:
? ? ? ? 寫過游戲的客爺都會深有體會,一個精靈如果就這么幾個狀態一點都不好玩,游戲想要好玩操作就一定要多變。所以瑪麗就應該會加速,會跑跳,會變走邊開槍,此時瑪麗應該會很多復合狀態。
? ? ? ? 這樣一條一條寫下去別想找朋友結婚生孩子了,稍微有一點需求變動加班就不是一時半會兒的。
? ? ? ? 所以可以根據剛才小可總結的狀態模式兩大特點來判斷這個需求是否適合狀態模式,首先他是一個對象且有多種私有狀態,其次這個對象需要一個環境方法來對自己的狀態做出變化。
? ? ? ? 整理好了思路我們來擼個代碼試試吧??
? ? ? ? 首先瑪麗是一個對象,他有一個私有的狀態對象。
? ? ? ? 然后為了能讓瑪麗改變狀態,需要一個環境方法,這個方法寫在原型上吧
? ? ? ? 這個方法我寫的和作者原著上不太一樣,作者是通過changeStatus方法去收集精靈的狀態變化,然后再通過別的方法來釋放所有狀態對應的方法。而在下認為,在我們按下手柄的瞬間其實就應該立刻去更改精靈狀態變化。所以我將狀態收集與狀態執行寫成了一個方法。
? ? ? ? 所以現在通過這種狀態模式的設計,我們的小瑪麗(mmm)不光能在我們的命令下開槍,還能在我們同時按下方向鍵的時候大跳!是不是很開心啊
? ? ? ? 狀態模式就這么介紹完畢了,為什么要第一個說它呢,因為也算是用的比較廣泛,同時也為了下一個備受歡迎的策略模式埋下伏筆,很多和在下一樣的客爺分不清策略和狀態,其實~無所謂,只要記住大體的設計思維,工作中能做到代碼優化避免無效加班,管他叫什么模式呢。
? ? ? ? 終于到了廢話時間,經過在下的努力,終于找到了一家在業內還比較健康的互聯網公司。在這個公司都在優化裁員的時期還在招聘的一定都是牛逼的公司,在這個狼多肉少的時期還敢裸辭的人也一定有點本事。明天就要去新公司報道了,期待能在這個地方大干一場。??