状态模式介绍
這里寫自定義目錄標題
- 狀態(tài)模式介紹
- 一、什么是狀態(tài)模式?
- 二、使用介紹
- 三、為什么我們需要它?(適用場景是什么)
- 小結(jié) 1、行為隨狀態(tài)改變而改變的場景。 2、條件、分支語句的代替者。
- 四、優(yōu)缺點
- 五、怎么實現(xiàn)
- 六、一個簡單的地鐵運行狀態(tài)的例子。
- 七、總結(jié):
- 項目開發(fā),單獨的狀態(tài)模式不適用我們的當前的合同狀態(tài)的流轉(zhuǎn),我們采用策略模式+狀態(tài)模式的方式實現(xiàn)
- 每天努力一點,每天都在進步
狀態(tài)模式介紹
一、什么是狀態(tài)模式?
在狀態(tài)模式(State Pattern)中,類的行為是基于它的狀態(tài)改變的。這種類型的設計模式屬于行為型模式。
在狀態(tài)模式中,我們創(chuàng)建表示各種狀態(tài)的對象和一個行為隨著狀態(tài)對象改變而改變的 context 對象。
狀態(tài)模式也稱狀態(tài)機(State Machine)、對象行為型態(tài)。簡單一句話解釋這個設計模式就是:用對象定義具體狀態(tài),調(diào)用時指向具體狀態(tài)對象的方法。
二、使用介紹
意圖:允許對象在內(nèi)部狀態(tài)發(fā)生改變時改變它的行為,對象看起來好像修改了它的類。
主要解決:對象的行為依賴于它的狀態(tài)(屬性),并且可以根據(jù)它的狀態(tài)改變而改變它的相關(guān)行為。
何時使用:代碼中包含大量與對象狀態(tài)有關(guān)的條件語句。
如何解決:將各種具體的狀態(tài)類抽象出來。
關(guān)鍵代碼:通常命令模式的接口中只有一個方法。而狀態(tài)模式的接口中有一個或者多個方法。而且,狀態(tài)模式的實現(xiàn)類的方法,一般返回值,或者是改變實例變量的值。也就是說,狀態(tài)模式一般和對象的狀態(tài)有關(guān)。實現(xiàn)類的方法有不同的功能,覆蓋接口中的方法。狀態(tài)模式和命令模式一樣,也可以用于消除 if…else 等條件選擇語句。
注意事項:在行為受狀態(tài)約束的時候使用狀態(tài)模式,而且狀態(tài)不超過 5 個。
三、為什么我們需要它?(適用場景是什么)
業(yè)務中免不了不同狀態(tài)做不同處理的代碼,簡單情況下我們只需要用if-else,switch-case就可以實現(xiàn)。以下情況,請考慮使用狀態(tài)機模式:從1到5,越往后的情況越適用。1.if后面的條件語句長,過長的條件使得代碼閱讀性差,更糟糕的是過多條件嚴重妨礙梳理邏輯。2.if-else數(shù)量多,與第一條有相似之處,過多的情況對于梳理代碼流程是不利的,數(shù)量過多之后代碼累贅加劇。3.if-else中的操作代碼多且復雜,這將使得方法體變得極其龐大,往往使得幾個if-else之間相隔天涯,對于把握代碼全局是不利的。4.if,if-else,else if...邏輯關(guān)系復雜,邏輯關(guān)系復雜往往捋一遍不夠,多捋幾遍就會繞進去,寫出來代碼也不容易發(fā)現(xiàn)隱患,或者往往要調(diào)試很久才發(fā)現(xiàn)漏掉的情況。5.對于這部分的需求改動頻繁,如果有之前的不適之癥,加上這個,就不解釋了。小結(jié) 1、行為隨狀態(tài)改變而改變的場景。 2、條件、分支語句的代替者。
四、優(yōu)缺點
優(yōu)點:1.代碼結(jié)構(gòu)化,易于維護、擴展。2.每個狀態(tài)只需要關(guān)心自己內(nèi)部的實現(xiàn),而不會影響到其他的,耦合降低。缺點: 1.有多少的狀態(tài)就得有多少的類,因此會創(chuàng)建大量的類。 2.代碼結(jié)構(gòu)變得復雜,不再是單個類中寫滿邏輯。五、怎么實現(xiàn)
實現(xiàn)方式有三部分: 1. 狀態(tài)擁有者的實體模型。 2. 狀態(tài)接口(也可使用抽象類),定義業(yè)務方法。 3. 狀態(tài)的各個具體實現(xiàn)類,分別實現(xiàn)業(yè)務方法。六、一個簡單的地鐵運行狀態(tài)的例子。
第1部分 實體模型的代碼 第2部分 狀態(tài)接口的代碼 第3部分 狀態(tài)的各個具體實現(xiàn)類的代碼
七、總結(jié):
1.狀態(tài)機模式:允許對象在內(nèi)部狀態(tài)改變時改變它的行為,對象看起來就好像修改了它的類(每個狀態(tài)可以做出不一樣的動作); 2.擁有多個狀態(tài)的對象(Context)只需要實現(xiàn)需要的操作,每次接收輸入的時候(request方法調(diào)用),只需要交給當前的狀態(tài)去處理,而每個狀態(tài)不需要知道自己之前的狀態(tài)是什么,只需要知道接收到什么樣的輸入(或者沒輸入)而做出相應的操作和自己下一個狀態(tài)是什么即可; 3.適當?shù)漠嫵鱿到y(tǒng)的狀態(tài)轉(zhuǎn)換圖,可以更清晰地實現(xiàn)系統(tǒng)狀態(tài)機。項目開發(fā),單獨的狀態(tài)模式不適用我們的當前的合同狀態(tài)的流轉(zhuǎn),我們采用策略模式+狀態(tài)模式的方式實現(xiàn)
`public interface ContractState {
String CONTRACT_STATE_PREFIX = "ContractState-";/*** 0 刪除無效狀態(tài)* @param contract*/ default void inActive(Contract contract) { }/*** 1 待發(fā)起 待簽約* @param contract*/ default void waitingForLaunch(Contract contract) { }/*** 2 正常合同,入場通過* @param contract*/ default void active(Contract contract) { } 。。。。}`
`public class ContractStatesMachine {
private ContractState currentState;public ContractState getCurrentState(ContractStatus contractStatus) {currentState = PlatformContext.getComponent(ContractState.CONTRACT_STATE_PREFIX + contractStatus.name());if (currentState == null) {currentState = PlatformContext.getComponent(ContractState.CONTRACT_STATE_PREFIX + ContractStatus.INACTIVE.name());}return currentState; }public void inactive(Contract contract) {currentState.inActive(contract); }public void waitingForLaunch(Contract contract) {currentState.waitingForLaunch(contract); }public void active(Contract contract) {currentState.active(contract); } 。。。}`
`public class ContractStatesServiceImpl {
// 狀態(tài)的默認實現(xiàn)父類
private static final Logger LOGGER = LoggerFactory.getLogger(ContractStatesServiceImpl.class);
}`
`
@Component(ContractState.CONTRACT_STATE_PREFIX + “ACTIVE”)
public class ActiveState extends ContractStatesServiceImpl implements ContractState {
}`
調(diào)用 contractStateMachine.getCurrentState(ContractStatus.WAITING_FOR_LAUNCH).waitingForApproval(contract);
每天努力一點,每天都在進步
總結(jié)
- 上一篇: Excel的简单编程
- 下一篇: sql server case when