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