状态设计模式示例
本文是我們名為“ Java設計模式 ”的學院課程的一部分。
 在本課程中,您將深入研究大量的設計模式,并了解如何在Java中實現和利用它們。 您將了解模式如此重要的原因,并了解何時以及如何應用模式中的每一個。 在這里查看 ! 
目錄
1.簡介 2.什么是狀態設計模式 3.實施狀態設計模式 4.何時使用狀態設計模式 5. Java中的狀態設計模式 6.下載源代碼1.簡介
為了說明“狀態設計模式”的使用,讓我們幫助一家正在尋求制造烹飪機器人的公司。 該公司想要一個簡單的機器人,它可以簡單地走路和煮飯。 用戶可以通過遙控器使用一組命令來操作機器人。 當前,機器人可以做三件事,它可以走路,做飯或關閉。
該公司已設置協議來定義機器人的功能。 如果機器人處于“開啟”狀態,則可以命令它行走。 如果要求烹飪,狀態將變為“烹飪”,或者如果設置為“關閉”,則將其關閉。
同樣,處于“烹飪”狀態時,它可以走路或做飯,但不能關閉。 最后,當處于“關閉”狀態時,當用戶命令它走路但不能在關閉狀態下烹飪時,它將自動上走。
這可能看起來像是一個簡單的實現:機器人類具有一組方法,如走動,烹飪,關閉以及狀態(如打開,烹飪和關閉)。 我們可以使用if-else分支或使用switch來實現公司設置的協議。 但是過多的if-else或switch語句將造成維護的噩夢,因為將來的復雜性可能會增加。
您可能認為我們可以使用if-else語句來實現此目的,但是隨著更改的來臨,代碼將變得更加復雜。 需求清楚地表明,對象的行為確實基于該對象的狀態。 我們可以使用狀態設計模式,該模式將對象的狀態封裝到另一個單獨的類中,并使上下文類獨立于任何狀態更改。
首先讓我們了解狀態設計模式,然后將其實現以解決上述問題。
2.什么是狀態設計模式
狀態設計模式允許對象在其內部狀態更改時更改其行為。 該對象似乎將更改其類。
可以將對象的狀態定義為在任何給定時間點的確切條件,具體取決于其屬性或屬性的值。 由類實現的方法集構成其實例的行為。 只要它的屬性值發生變化,我們就說對象的狀態已發生變化。
狀態模式可用于為類設計有效的結構,該類的典型實例可以存在于許多不同的狀態中,并根據其所處的狀態而表現出不同的行為。換句話說,對于此類對象,類,其某些或全部行為完全受其當前狀態影響。 在狀態設計模式術語中,此類稱為Context類。 當內部狀態發生變化時, Context對象可以更改其行為,也稱為有狀態對象。
狀態模式建議將特定于狀態的行為從Context類中移到一組單獨的類中,這些類稱為State類。 Context對象可以存在的許多不同狀態中的每一個都可以映射到單獨的State類中。 State類的實現包含特定于給定狀態的上下文行為,而不是上下文本身的整體行為。 從某種意義上說,上下文充當狀態對象集的客戶端,因為它利用不同的狀態對象向無縫使用上下文的應用程序對象提供必要的特定于狀態的行為。
通過將特定于狀態的行為封裝在單獨的類中,上下文實現變得更易于閱讀:無需太多條件語句(例如if-else或switch-case構造)。 首次創建Context對象時,它將使用其初始State對象進行初始化。 該State對象成為上下文的當前State對象。 通過用新的State對象替換當前的State對象,上下文將轉換為新的狀態。
使用上下文的客戶端應用程序不負責為上下文指定當前的State對象,而是代表特定狀態的每個State類均應提供將上下文轉換為其他狀態的必要實現。 當應用程序對象調用Context方法(行為)時,它將方法調用轉發到其當前的State對象。
圖1 –類圖
語境
- 定義客戶感興趣的界面。
 - 維護定義當前狀態的ConcreteState子類的實例。
 
州
- 定義用于封裝與Context的特定狀態關聯的行為的接口。
 
ConcreteState子類
- 每個子類都實現與Context狀態關聯的行為。
 
3.實施狀態設計模式
以下是RoboticState接口,其中包含機器人的行為。
package com.javacodegeeks.patterns.statepattern;public interface RoboticState {public void walk();public void cook();public void off();}Robot類是實現RoboticState接口的具體類。 該類包含機器人可能處于的所有可能狀態的集合。
package com.javacodegeeks.patterns.statepattern;public class Robot implements RoboticState{private RoboticState roboticOn;private RoboticState roboticCook;private RoboticState roboticOff;private RoboticState state;public Robot(){this.roboticOn = new RoboticOn(this);this.roboticCook = new RoboticCook(this);this.roboticOff = new RoboticOff(this);this.state = roboticOn;}public void setRoboticState(RoboticState state){this.state = state;}@Overridepublic void walk() {state.walk();}@Overridepublic void cook() {state.cook();}@Overridepublic void off() {state.off();}public RoboticState getRoboticOn() {return roboticOn;}public void setRoboticOn(RoboticState roboticOn) {this.roboticOn = roboticOn;}public RoboticState getRoboticCook() {return roboticCook;}public void setRoboticCook(RoboticState roboticCook) {this.roboticCook = roboticCook;}public RoboticState getRoboticOff() {return roboticOff;}public void setRoboticOff(RoboticState roboticOff) {this.roboticOff = roboticOff;}public RoboticState getState() {return state;}public void setState(RoboticState state) {this.state = state;}}該類初始化所有狀態并將當前狀態設置為on。
現在,我們將看到機器人的所有具體狀態。 機器人將隨時處于任何一種狀態。
package com.javacodegeeks.patterns.statepattern;public class RoboticOn implements RoboticState{private final Robot robot;public RoboticOn(Robot robot){this.robot = robot;}@Overridepublic void walk() {System.out.println("Walking...");}@Overridepublic void cook() {System.out.println("Cooking...");robot.setRoboticState(robot.getRoboticCook());}@Overridepublic void off() {robot.setState(robot.getRoboticOff());System.out.println("Robot is switched off");}}package com.javacodegeeks.patterns.statepattern;public class RoboticCook implements RoboticState{private final Robot robot;public RoboticCook(Robot robot){this.robot = robot;}@Overridepublic void walk() {System.out.println("Walking...");robot.setRoboticState(robot.getRoboticOn());}@Overridepublic void cook() {System.out.println("Cooking...");}@Overridepublic void off() {System.out.println("Cannot switched off while cooking...");} }package com.javacodegeeks.patterns.statepattern;public class RoboticOff implements RoboticState{private final Robot robot;public RoboticOff(Robot robot){this.robot = robot;}@Overridepublic void walk() {System.out.println("Walking...");robot.setRoboticState(robot.getRoboticOn());}@Overridepublic void cook() {System.out.println("Cannot cook at Off state.");}@Overridepublic void off() {System.out.println("Already switched off...");} }現在,讓我們測試代碼。
package com.javacodegeeks.patterns.statepattern;public class TestStatePattern {public static void main(String[] args) {Robot robot = new Robot();robot.walk();robot.cook();robot.walk();robot.off();robot.walk();robot.off();robot.cook();}}上面的代碼將導致以下輸出:
Walking... Cooking... Walking... Robot is switched off Walking... Robot is switched off Cannot cook at Off state.在上面的示例中,我們已經看到通過將對象的狀態封裝到不同的類中可以使代碼易于管理和靈活。
狀態的任何更改只會影響該特定的類,我們可以在不更改現有代碼的情況下包括一個新狀態。 例如,我們包含一個備用狀態。 散步或做飯后,機器人進入待機模式以節省電量,然后我們再次步行,做飯或從待機模式下關閉。
為了實現所有這些,我們需要引入一個新的狀態類,并將該狀態包括在Robot類中。 以下是更改。
package com.javacodegeeks.patterns.statepattern;public class Robot implements RoboticState{private RoboticState roboticOn;private RoboticState roboticCook;private RoboticState roboticOff;private RoboticState roboticStandby;private RoboticState state;public Robot(){this.roboticOn = new RoboticOn(this);this.roboticCook = new RoboticCook(this);this.roboticOff = new RoboticOff(this);this.roboticStandby = new RoboticStandby(this);this.state = roboticOn;}public void setRoboticState(RoboticState state){this.state = state;}@Overridepublic void walk() {state.walk();setState(getRoboticStandby());}@Overridepublic void cook() {state.cook();setState(getRoboticStandby());}@Overridepublic void off() {state.off();}public RoboticState getRoboticOn() {return roboticOn;}public void setRoboticOn(RoboticState roboticOn) {this.roboticOn = roboticOn;}public RoboticState getRoboticCook() {return roboticCook;}public void setRoboticCook(RoboticState roboticCook) {this.roboticCook = roboticCook;}public RoboticState getRoboticOff() {return roboticOff;}public void setRoboticOff(RoboticState roboticOff) {this.roboticOff = roboticOff;}public RoboticState getState() {return state;}public void setState(RoboticState state) {this.state = state;}public RoboticState getRoboticStandby() {return roboticStandby;}public void setRoboticStandby(RoboticState roboticStandby) {this.roboticStandby = roboticStandby;}}package com.javacodegeeks.patterns.statepattern;public class RoboticStandby implements RoboticState{private final Robot robot;public RoboticStandby(Robot robot){this.robot = robot;}@Overridepublic void walk() {System.out.println("In standby state...");robot.setState(robot.getRoboticOn());System.out.println("Walking...");}@Overridepublic void cook() {System.out.println("In standby state...");robot.setRoboticState(robot.getRoboticCook());System.out.println("Cooking...");}@Overridepublic void off() {System.out.println("In standby state...");robot.setState(robot.getRoboticOff());System.out.println("Robot is switched off");}}現在,以上代碼更改將導致以下輸出:
Walking... In standby state... Cooking... In standby state... Walking... In standby state... Robot is switched off Walking... In standby state... Robot is switched off Cannot cook at Off state.4.何時使用狀態設計模式
在以下兩種情況下,請使用State模式:
- 對象的行為取決于其狀態,并且它必須在運行時根據該狀態更改其行為。
 - 操作具有取決于對象狀態的大型,多部分條件語句。 此狀態通常由一個或多個枚舉常量表示。 通常,幾個操作將包含此相同的條件結構。 State模式將條件的每個分支放在單獨的類中。 這樣一來,您就可以將對象的狀態視為獨立于其他對象而獨立變化的對象。
 
5. Java中的狀態設計模式
- javax.faces.lifecycle.LifeCycle#execute()
 
6.下載源代碼
這是關于狀態設計模式的課程。 您可以在此處下載源代碼: StatePattern-Project
翻譯自: https://www.javacodegeeks.com/2015/09/state-design-pattern.html
總結
                            
                        - 上一篇: 小企业会计制度备案表怎么填(小企业会计制
 - 下一篇: DDOS黑客(黑客ddos银行)