Java设计模式—状态模式
(尊重勞動(dòng)成果,轉(zhuǎn)載請(qǐng)注明出處:https://blog.csdn.net/qq_25827845/article/details/52468077冷血之心的博客)
目錄
定義如下:
個(gè)人理解:
通用類圖:
角色介紹:
● State——抽象狀態(tài)角色
● ConcreteState——具體狀態(tài)角色
● Context——環(huán)境角色
通用源代碼:
場景類:
狀態(tài)模式的優(yōu)點(diǎn):
狀態(tài)模式的缺點(diǎn):
使用場景:
狀態(tài)模式又是一個(gè)比較難的設(shè)計(jì)模式
定義如下:
當(dāng)一個(gè)對(duì)象內(nèi)在狀態(tài)改變時(shí)允許其改變行為,這個(gè)對(duì)象看起來像改變了其類。
個(gè)人理解:
通俗的講,狀態(tài)模式就是狀態(tài)的改變引起了行為的改變,但是,我們只能看到行為的改變,看不到狀態(tài)的改變。
通用類圖:
角色介紹:
● State——抽象狀態(tài)角色
接口或抽象類,負(fù)責(zé)對(duì)象狀態(tài)定義,并且封裝環(huán)境角色以實(shí)現(xiàn)狀態(tài)切換。
● ConcreteState——具體狀態(tài)角色
每一個(gè)具體狀態(tài)必須完成兩個(gè)職責(zé):本狀態(tài)的行為管理以及趨向狀態(tài)處理,通俗地說,就是本狀態(tài)下要做的事情,以及本狀態(tài)如何過渡到其他狀態(tài)。
● Context——環(huán)境角色
定義客戶端需要的接口,并且負(fù)責(zé)具體狀態(tài)的切換。
舉個(gè)例子:
? ? ? ? 狀態(tài)模式提供了一種對(duì)物質(zhì)運(yùn)動(dòng)的另一個(gè)觀察視角,通過狀態(tài)變更促使行為的變化,就類似水的狀態(tài)變更一樣,一碗水的初始狀態(tài)是液態(tài),通過加熱轉(zhuǎn)變?yōu)闅鈶B(tài),狀態(tài)的改變同時(shí)也引起體積的擴(kuò)大,然后就產(chǎn)生了一個(gè)新的行為:鳴笛或頂起壺蓋。
通用源代碼:
//抽象狀態(tài)角色 public abstract class State {//定義一個(gè)環(huán)境角色,提供子類訪問protected Context context;//設(shè)置環(huán)境角色public void setContext(Context _context){this.context = _context;}//行為1public abstract void handle1();//行為2public abstract void handle2(); }抽象狀態(tài)中聲明一個(gè)環(huán)境角色,提供各個(gè)狀態(tài)類自行訪問,并且提供所有狀態(tài)的抽象行為,由各個(gè)實(shí)現(xiàn)類實(shí)現(xiàn)。
//具體狀態(tài)角色 public class ConcreteState1 extends State { @Overridepublic void handle1() {//本狀態(tài)下必須處理的邏輯}@Overridepublic void handle2() {//設(shè)置當(dāng)前狀態(tài)為stat2super.context.setCurrentState(Context.STATE2);//過渡到state2狀態(tài),由Context實(shí)現(xiàn)super.context.handle2();} } public class ConcreteState2 extends State {@Overridepublic void handle1() { //設(shè)置當(dāng)前狀態(tài)為state1super.context.setCurrentState(Context.STATE1);//過渡到state1狀態(tài),由Context實(shí)現(xiàn)super.context.handle1();}@Overridepublic void handle2() {//本狀態(tài)下必須處理的邏輯} }具體狀態(tài)角色有兩個(gè)職責(zé):處理本狀態(tài)必須完成的任務(wù),決定是否可以過渡到其他狀態(tài)。
//環(huán)境角色 public class Context {//定義狀態(tài)public final static State STATE1 = new ConcreteState1();public final static State STATE2 = new ConcreteState2();//當(dāng)前狀態(tài)private State CurrentState;//獲得當(dāng)前狀態(tài)public State getCurrentState() {return CurrentState;}//設(shè)置當(dāng)前狀態(tài)public void setCurrentState(State currentState) {this.CurrentState = currentState;//切換狀態(tài)this.CurrentState.setContext(this);}//行為委托public void handle1(){this.CurrentState.handle1();}public void handle2(){this.CurrentState.handle2();}}環(huán)境角色有兩個(gè)不成文的約束:
- 把狀態(tài)對(duì)象聲明為靜態(tài)常量,有幾個(gè)狀態(tài)對(duì)象就聲明幾個(gè)靜態(tài)常量。
- 環(huán)境角色具有狀態(tài)抽象角色定義的所有行為,具體執(zhí)行使用委托方式。
場景類:
public class Client {public static void main(String[] args) {//定義環(huán)境角色Context context = new Context();//初始化狀態(tài)context.set CurrentState(new ConcreteState1());//行為執(zhí)行context.handle1();context.handle2();} }如上所示:我們只看到了行為發(fā)生改變。
?
狀態(tài)模式的優(yōu)點(diǎn):
● 結(jié)構(gòu)清晰
避免了過多的switch...case或者if...else語句的使用,避免了程序的復(fù)雜性,提高系統(tǒng)的可維護(hù)性。
● 遵循設(shè)計(jì)原則
很好地體現(xiàn)了開閉原則和單一職責(zé)原則,每個(gè)狀態(tài)都是一個(gè)子類,你要增加狀態(tài)就要增加子類,你要修改狀態(tài),你只修改一個(gè)子類就可以了。
● 封裝性非常好
這也是狀態(tài)模式的基本要求,狀態(tài)變換放置到類的內(nèi)部來實(shí)現(xiàn),外部的調(diào)用不用知道類內(nèi)部如何實(shí)現(xiàn)狀態(tài)和行為的變換。
狀態(tài)模式的缺點(diǎn):
每一個(gè)狀態(tài)都是一個(gè)子類,容易產(chǎn)生子類膨脹的問題。
使用場景:
● 行為隨狀態(tài)改變而改變的場景
? ? ? ?這也是狀態(tài)模式的根本出發(fā)點(diǎn),例如權(quán)限設(shè)計(jì),人員的狀態(tài)不同即使執(zhí)行相同的行為結(jié)果也會(huì)不同,在這種情況下需要考慮使用狀態(tài)模式。
● 條件、分支判斷語句的替代者
? ? ? ?在程序中大量使用switch語句或者if判斷語句會(huì)導(dǎo)致程序結(jié)構(gòu)不清晰,邏輯混亂,使用狀態(tài)模式可以很好地避免這一問題,它通過擴(kuò)展子類實(shí)現(xiàn)了條件的判斷處理。
?
如果對(duì)你有幫助,記得點(diǎn)贊哦~歡迎大家關(guān)注我的博客,我會(huì)持續(xù)更新,如果有什么問題,可以進(jìn)群366533258一起交流學(xué)習(xí)哦~
?
總結(jié)
以上是生活随笔為你收集整理的Java设计模式—状态模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业邮箱WebMail协助办公功能盘点
- 下一篇: Word2016给重复文字全部添加高亮,