閱讀本文大約需要 4.5 分鐘
文章經作者老姚,授權轉載
今天說說搞對象這件事情兒。
我們經常愛問一個人,你為啥還單着?
對方的回答無非是如下這兩種:
- 沒遇到合适的。
- 太忙了,沒有時間。
其他回答,要麼能歸于這二者其一,要麼二者兼顧。
然而,在我看來,這二者分别對應了政策模式和狀态模式。
使用背景語言的同學都知道政策模式和狀态模式是對雙胞胎,隻有出生之後才分開。
又或說二者長得十分像,但是性格迥然不同。
我認為這種說法沒有說到點子上,準确地說二者是情侶,一男一女。
1. 政策模式
那麼什麼是政策模式?
政策、政策,講究的是做一件事情可以有不同的招數。
是以很多書籍都愛用“錦囊妙計”來說它。
var doSomething1 = function() {
console.log('xxx');
};
var doSomething2 = function() {
console.log('yyy');
}
// 核心
var doSomething = function(strategy) {
if (strategy == 'xxx') doSomething1();
if (strategy == 'yyy') doSomething2();
};
doSomething('xxx'); // xxx
doSomething('yyy'); // yyy
複制
上面的代碼就是政策的一種
if-else
實作方式。
在前端使用可以如下實作政策模式:
var doSomething = function(strategy) {
strategys[strategy]();
};
var strategys = {
xxx: function() {
console.log('xxx');
},
yyy: function() {
console.log('yyy');
}
};
doSomething('xxx'); // xxx
doSomething('yyy'); // yyy
複制
政策模式,你傳什麼,我就使用什麼招數!
2. 狀态模式
政策模式的分析暫告一段落,我們再來看看什麼是狀态?
狀态、狀态,今天沒心情上班,此心情就是狀态。
之前看過一個段子:
A:來了?
B:來了。
A:來了?
B:來了。
A:來嗎?
B:不來了。
這個段子的含義是,能不能“來”,取決于目前的狀态。
一個具體例子,開關,它最能展現出狀态。
var state = 'off';
var doSomething1 = function() {
if (state == 'off') {
console.log('doSomething1 and turn to on');
flag = 'on';
}
if (state == 'on') {
console.log('doSomething1 else');
}
};
var doSomething2 = function() {
if (state == 'off') {
console.log('doSomething2');
}
if (state == 'on') {
console.log('doSomething2 else and turn to off');
flag = 'off';
}
}
doSomething1(); // doSomething1 and turn to on
doSomething1(); // doSomething1 else
doSomething2(); // doSomething2 else and turn to off
doSomething2(); // doSomething2
複制
每次去做事情時,結果是取決于目前的狀态的。
上述邏輯改成狀态模式實作:
var doSomething1 = function () {
state.doSomething1();
};
var doSomething2 = function () {
state.doSomething2();
};
var off = {
doSomething1: function () {
console.log('doSomething1 and turn to on');
state = on;
},
doSomething2: function () {
console.log('doSomething2');
}
}
var on = {
doSomething1: function () {
console.log('doSomething1 else');
},
doSomething2: function () {
console.log('doSomething2 else and turn to off');
state = off;
}
}
var state = off
doSomething1(); // doSomething1 and turn to on
doSomething1(); // doSomething1 else
doSomething2(); // doSomething2 else and turn to off
doSomething2(); // doSomething2
複制
ok,這就是狀态指導行為。
3. 情侶關系
政策模式和狀态模式是什麼以及如何簡單實作,應該相對清楚了。
使用相應模式後,代碼變得清晰了,也容易應對變化。
可以新增不同的政策,可以新增不同的狀态。
現在我們來看看他倆為啥是情侶關系?
政策模式根據外界條件來選取不同的政策。
狀态模式根據内部狀态來決定不同的反應。
"有象斯有對,對必反其為"。
一個外,一個内。
這兩句看起來是對仗工整。但是看二者代碼,卻沒有這麼覺得呢?
發現政策模式代碼量小,而狀态模式代碼量大,後者幾乎是前者的兩倍。
說二者是男女,政策應該是男的,而狀态是女的。
男的關心的是如何快速解決問題,拿出解決方法。
女人關心的是目前心情和情緒的安撫,關注内在狀态。
從上面的代碼量來看,女生想的心事兒比較多。
下面讓例子代碼量對等一下。
這裡用政策模式來嘗試模拟你的技能和興趣。
var 絕技 = {
思考: function () {
console.log("胡思亂想");
},
看書: function() {
console.log('一氣呵成');
}
};
var 愛好 = {
吹牛: function () {
console.log("牛上天了");
},
抽煙: function() {
console.log("騰雲駕霧");
}
};
var 你 = {
展示絕技: function(strategy) {
絕技[strategy]();
},
展示愛好: function(strategy) {
愛好[strategy]();
}
};
你.展示絕技("思考"); // 胡思亂想
你.展示絕技("看書"); // 一氣呵成
你.展示愛好("吹牛"); // 牛上天了
你.展示愛好("抽煙"); // 騰雲駕霧
複制
上述代碼封裝了兩組算法,每組算法内由外界來決定選擇具體某種算法。
那麼對于狀态模式,也來寫一下自己。
var 煩 = {
吹牛: function() {
console.log('吹一吹,心情大爽啊');
目前心情 = 爽;
},
抽煙: function() {
console.log('心情不好的時候,越抽越沒勁');
}
};
var 爽 = {
吹牛: function() {
console.log('越吹越爽');
},
抽煙: function() {
console.log('一想起吸煙有害健康,開始不爽起來');
目前心情 = 煩;
}
};
var 目前心情 = 煩;
var 老姚 = {
吹牛: function() {
目前心情["吹牛"]();
},
抽煙: function() {
目前心情["抽煙"]();
}
};
老姚.吹牛(); // 吹一吹,心情大爽啊
老姚.吹牛(); // 越吹越爽
老姚.抽煙(); // 一想起吸煙有害健康,開始不爽起來
老姚.抽煙(); // 心情不好的時候,越抽越沒勁
複制
狀态模式是封裝一個個狀态,狀态封裝所有行為,具體某個行為,由目前的狀态來決定。
現在代碼量等同了。有看出了一種對偶關系了嗎?
政策模式:定義了一系列的算法,并将每一個算法封裝起來,而且使它們還可以互相替換。政策模式讓算法獨立于使用它的客戶而獨立變化。
狀态模式:允許一個對象在其内部狀态改變時改變它的行為。對象看起來似乎修改了它的類。
二者定義裡,都有“不同”這個詞語。
有象斯有對,對必反其為。
政策模式取決于傳進來的政策。
狀态取決于上一次調用後,目前的狀态。
但是,政策模式好了解。也很好應用。宛如一個少年,沒啥心思。
狀态模式,我覺得就比較屌了。
對于一個複雜的過程,狀态模式才能發揮真正實力。
關鍵你如何去劃分狀态,構造出狀态機。
看來女人不隻是半邊天那麼簡單。
對于狀态模式的使用,讓我想起一個故事。
說是有一位精神病人,跑到屋裡,把門從裡面反鎖。
然後大聲對屋外喊着,我要把你們鎖進裡面,永遠都别想出去!!
不知道我有沒有說清楚,希望有所幫助。
也歡迎閱讀老姚的《JS正則迷你書》。https://github.com/qdlaoyao/js-regex-mini-book
推薦閱讀
我的公衆号能帶來什麼價值?(文末有送書規則,一定要看)
每個前端工程師都應該了解的圖檔知識(長文建議收藏)
為什麼現在面試總是面試造火箭?