狀態模式(State)容許一個對象在其內部狀態改變的時候改變它的行爲,對象看起來彷佛修改了它的類。
其實就是用一個對象或者數組記錄一組狀態,每一個狀態對應一個實現,實現的時候根據狀態挨個去運行實現。html
好比超級瑪麗,就可能同時有好幾個狀態好比 跳躍,移動,射擊,蹲下 等,若是對這些動做一個個進行處理判斷,須要多個if-else
或者switch
不只醜陋不說,並且在遇到有組合動做的時候,實現就會變的更爲複雜,這裏可使用狀態模式來實現。前端
狀態模式的思路是:首先建立一個狀態對象或者數組,內部保存狀態變量,而後內部封裝好每種動做對應的狀態,而後狀態對象返回一個接口對象,它能夠對內部的狀態修改或者調用。segmentfault
const SuperMarry = (function() { let _currentState = [], // 狀態數組 states = { jump() {console.log('跳躍!')}, move() {console.log('移動!')}, shoot() {console.log('射擊!')}, squat() {console.log('蹲下!')} } const Action = { changeState(arr) { // 更改當前動做 _currentState = arr return this }, goes() { console.log('觸發動做') _currentState.forEach(T => states[T] && states[T]()) return this } } return { change: Action.changeState, go: Action.goes } })() SuperMarry .change(['jump', 'shoot']) .go() // 觸發動做 跳躍! 射擊! .go() // 觸發動做 跳躍! 射擊! .change(['squat']) .go() // 觸發動做 蹲下!
這裏可使用ES6
的class
優化一下:設計模式
class SuperMarry { constructor() { this._currentState = [] this.states = { jump() {console.log('跳躍!')}, move() {console.log('移動!')}, shoot() {console.log('射擊!')}, squat() {console.log('蹲下!')} } } change(arr) { // 更改當前動做 this._currentState = arr return this } go() { console.log('觸發動做') this._currentState.forEach(T => this.states[T] && this.states[T]()) return this } } new SuperMarry() .change(['jump', 'shoot']) .go() // 觸發動做 跳躍! 射擊! .go() // 觸發動做 跳躍! 射擊! .change(['squat']) .go() // 觸發動做 蹲下!
狀態模式的使用場景也特別明確,有以下兩點:數組
簡而言之,當遇到不少同級if-else
或者switch
的時候,可使用狀態模式來進行簡化。緩存
本文是系列文章,能夠相互參考印證,共同進步~微信
網上的帖子大多深淺不一,甚至有些先後矛盾,在下的文章都是學習過程當中的總結,若是發現錯誤,歡迎留言指出~函數
參考:
《Javascript 設計模式》 - 張榮銘
設計模式之狀態模式
PS:歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~學習
另外能夠加入「前端下午茶交流羣」微信羣,長按識別下面二維碼便可加我好友,備註加羣,我拉你入羣~優化