前言
狀態(tài)模式顧名思義,它是依據(jù)狀態(tài)的不同印衔,調(diào)用同樣的方法卻有不同的行為。每一個(gè)狀態(tài)都有一個(gè)共同的狀態(tài)基類,狀態(tài)模式的目的就是在狀態(tài)改變的時(shí)候躲惰,行為也跟著改變。
多用于一個(gè)對(duì)象的行為取決于它的狀態(tài)变抽,且必須在運(yùn)行時(shí)根據(jù)狀態(tài)改變它的行為础拨。或者一個(gè)對(duì)象中有大量的操作判斷比如if else switch绍载,且依賴于該對(duì)象的狀態(tài)诡宗。
狀態(tài)模式定義
依據(jù)狀態(tài)的不同,調(diào)用同樣的方法卻有不同的行為
狀態(tài)模式舉例
我們舉一個(gè)車輛限行的例子:
重慶嘉華大橋最近實(shí)行限號(hào)措施逛钻,星期一限行尾數(shù)1和6僚焦、星期二限行尾數(shù)2和7,這里為了省略篇幅曙痘,我們只寫周一周二兩種狀態(tài)
先抽象出一個(gè)接口方法芳悲,判斷是否限行
public interface Check {
boolean limit(int lastNumber);
}
然后定義周一和周二兩種不同狀態(tài)同個(gè)limit方法下,不同的處理行為边坤。
public class Monday implements Check {
@Override
public boolean limit(int lastNumber) {
if (lastNumber == 1 || lastNumber == 6) {
return true;
}
return false;
}
}
public class Tuesday implements Check {
@Override
public boolean limit(int lastNumber) {
if (lastNumber == 2 || lastNumber == 7) {
return true;
}
return false;
}
}
最后定義一個(gè)判斷限行的類名扛,來(lái)統(tǒng)一管理和處理
public class LimitLine {
private Check check;
public void setCheck(Check check) {
this.check = check;
}
public boolean getLimitLine (int lastNumber) {
return check.limit(lastNumber);378915406@qq.com
}
}
到此,狀態(tài)模式就寫完了茧痒,然后我們看一下怎么調(diào)用它
Monday monday = new Monday();
Tuesday tuesday = new Tuesday();
LimitLine limitLine = new LimitLine();
limitLine.setCheck(monday);
boolean mondayLimitOne = limitLine.getLimitLine(1);
boolean mondayLimitTwo = limitLine.getLimitLine(2);
limitLine.setCheck(tuesday);
boolean tuesdayLimitOne = limitLine.getLimitLine(1);
boolean tuesdayLimitTwo = limitLine.getLimitLine(2);
Log.d("State","mondayLimitOne = " + mondayLimitOne);
Log.d("State","mondayLimitTwo = " + mondayLimitTwo);
Log.d("State","tuesdayLimitOne = " + tuesdayLimitOne);
Log.d("State","tuesdayLimitTwo = " + tuesdayLimitTwo);
LOG輸出如下:
D/State: mondayLimitOne = true
D/State: mondayLimitTwo = false
D/State: tuesdayLimitOne = false
D/State: tuesdayLimitTwo = true
狀態(tài)模式小結(jié)
現(xiàn)在來(lái)整體看下代碼肮韧,狀態(tài)模式結(jié)構(gòu)很簡(jiǎn)單,根據(jù)不同的狀態(tài)旺订,使用同種方法(接口)弄企,通過(guò)子類去實(shí)現(xiàn)不同的行為。對(duì)與這里的例子就是区拳,根據(jù)星期幾的不同拘领,去判斷限行。方法是判斷限行樱调,但是因?yàn)?018-11-10星期幾這個(gè)狀態(tài)的不同约素,相同的尾號(hào)條件,相同的判斷方法笆凌,得到不同的結(jié)果圣猎。
最后說(shuō)下狀態(tài)模式和策略模式的區(qū)別,雖然他們?cè)诖a結(jié)構(gòu)上幾乎相同乞而,但思想確實(shí)不同的送悔,最最最最最根本的區(qū)別點(diǎn)在于:
1、策略模式的側(cè)重點(diǎn)是提供不同的方法(策略)。
2放祟、狀態(tài)模式的行為是由狀態(tài)來(lái)決定鳍怨,不同狀態(tài)有不同的行為。
One more thing! 有的人或許會(huì)認(rèn)為策略模式和狀態(tài)模式就是一種模式跪妥,但不是這樣鞋喇。假設(shè)我們現(xiàn)在對(duì)一個(gè)數(shù)組從小到大排序,這個(gè)時(shí)候我們寫了兩個(gè)策略眉撵,一個(gè)冒泡排序侦香,一個(gè)插入排序。兩個(gè)策略纽疟。結(jié)果都能正常排序罐韩。所以策略模式的重點(diǎn)是不同的策略上。狀態(tài)模式就是本文所講污朽,重點(diǎn)在狀態(tài)上散吵。
結(jié)束語(yǔ)
狀態(tài)模式的應(yīng)用場(chǎng)景也很明顯,就是根據(jù)狀態(tài)的不同蟆肆,同種方法需要不同的行為矾睦。如果不用狀態(tài)模式,你可以寫if else 或者 switch語(yǔ)句炎功,但是這樣會(huì)很臃腫枚冗,且不好擴(kuò)展,比如本文的例子蛇损,你需要判斷周一到周天七個(gè)狀態(tài)赁温,這里的方法的代碼簡(jiǎn)單還好,如果很復(fù)雜淤齐。你的代碼就會(huì)顯得很臃腫股囊。耦合度高,增加了出錯(cuò)率更啄。用狀態(tài)模式則能很好的避免稚疹,且代碼結(jié)構(gòu)簡(jiǎn)單清晰。