【设计模式系列19】状态模式原理分析及其和策略模式,责任链模式的区别
狀態(tài)模式原理分析
- 設(shè)計模式系列總覽
- 前言
- 什么是狀態(tài)模式
- 狀態(tài)模式示例
- 狀態(tài)模式角色
- 狀態(tài)模式與責任鏈模式
- 狀態(tài)模式與策略模式
- 狀態(tài)模式應(yīng)用場景
- 狀態(tài)模式優(yōu)缺點
- 總結(jié)
設(shè)計模式系列總覽
| 三大工廠模式 | 登機入口 |
| 策略模式 | 登機入口 |
| 委派模式 | 登機入口 |
| 模板方法模式 | 登機入口 |
| 觀察者模式 | 登機入口 |
| 單例模式 | 登機入口 |
| 原型模式 | 登機入口 |
| 代理模式 | 登機入口 |
| 裝飾者模式 | 登機入口 |
| 適配器模式 | 登機入口 |
| 建造者模式 | 登機入口 |
| 責任鏈模式 | 登機入口 |
| 享元模式 | 登機入口 |
| 組合模式 | 登機入口 |
| 門面模式 | 登機入口 |
| 橋接模式 | 登機入口 |
| 中介者模式 | 登機入口 |
| 迭代器模式 | 登機入口 |
| 狀態(tài)模式 | 登機入口 |
| 解釋器模式 | 登機入口 |
| 備忘錄模式 | 登機入口 |
| 命令模式 | 登機入口 |
| 訪問者模式 | 登機入口 |
| 軟件設(shè)計7大原則和設(shè)計模式總結(jié) | 登機入口 |
前言
狀態(tài)對于我們開發(fā)者而言是相當熟悉的,平常開發(fā)中總是離不開對象的狀態(tài),比如我們審核流程,就是一個狀態(tài)不斷流轉(zhuǎn)的過程,訂單流程也是一個狀態(tài)不斷流轉(zhuǎn)的過程,而狀態(tài)模式就是為了更好地解決我們狀態(tài)流轉(zhuǎn)過程中的業(yè)務(wù)處理邏輯。
什么是狀態(tài)模式
狀態(tài)模式(State Pattern)也稱為狀態(tài)機模式(State Machine Pattern),是允許對象在內(nèi)部狀態(tài)發(fā)生改變的同時改變對象的行為,使得看起來像是修改了類一樣。
狀態(tài)模式中的類的行為是由狀態(tài)決定的,不同的狀態(tài)有不同的行為。狀態(tài)模式的意圖是讓一個對象在其內(nèi)部改變時行為也隨之一起改變。
狀態(tài)模式的核心就是給每一種狀態(tài)綁定一種行為。
好了,裝逼時刻又到了:Talk is cheap,Show you the code,先看一個非常簡單的例子。
狀態(tài)模式示例
下面我們就以訂單狀態(tài)的流轉(zhuǎn)來寫一個簡單的示例,我們假設(shè)訂單只有三個狀態(tài):待支付,待收貨,已收貨(完成)。
1、首先建立一個抽象的狀態(tài)類,這個類需要定義所有狀態(tài)的所有行為:
package com.zwx.design.pattern.state;public abstract class AbstractOrderState {protected OrderContext orderContext;public AbstractOrderState(OrderContext orderContext) {this.orderContext = orderContext;}public abstract void payOrder();public abstract void deliver();public abstract void receiveGoods(); }注意這里面集成了一個OrderContext對象,這個對象是用來負責狀態(tài)的切換的。
2、因為有三個狀態(tài),所以我們新建三個具體的狀態(tài)類來實現(xiàn)抽象狀態(tài)類:
- 待支付狀態(tài)類:
- 待發(fā)貨狀態(tài)類:
- 已收貨狀態(tài)類:
我們可以看到,每個狀態(tài)都綁定了一個行為(也可以支持綁定多個),并且在對應(yīng)的行為處理完畢之后會流轉(zhuǎn)到下一個狀態(tài),對于不屬于當前狀態(tài)的行為則做出相應(yīng)的回應(yīng)。
3、再建立一個狀態(tài)上下文環(huán)境類,用來負責具體狀態(tài)的切換:
package com.zwx.design.pattern.state;/*** @author zwx* @version 1.0* @date 2020/10/5* @since jdk1.8*/ public class OrderContext {AbstractOrderState waitPaid;AbstractOrderState waitDeliver;AbstractOrderState receiveGoods;AbstractOrderState currState;//當前狀態(tài)public OrderContext() {this.waitPaid = new WaitPaidOrderState(this);this.waitDeliver = new WaitDeliverOrderState(this);this.receiveGoods = new ReceiveGoodsOrderState(this);currState = waitPaid;}void setState(AbstractOrderState state){this.currState = state;}public void payOrder(){currState.payOrder();}public void deliver(){currState.deliver();}public void receiveGoods(){currState.receiveGoods();} }可以看到,這個類里面也有點委派模式的影子,不同的行為委派給對應(yīng)的對象進行處理而自己不做處理,只負責狀態(tài)的切換。
4、最后再新建一個測試類進行測試:
package com.zwx.design.pattern.state;public class TestState {public static void main(String[] args) {OrderContext orderContext = new OrderContext();orderContext.payOrder();orderContext.deliver();orderContext.receiveGoods();} }輸出結(jié)果為:
支付成功 商品已發(fā)貨并送達目的地 用戶已收到商品,此次交易結(jié)束狀態(tài)模式角色
從上面示例中,我們可以得出狀態(tài)模式主要有3個角色:
- 環(huán)境類角色(Context):定義客戶端需要的接口,內(nèi)部維護一個當前狀態(tài)實例,并負責具體狀態(tài)的切換。
- 抽象狀態(tài)角色(State):定義每個狀態(tài)下對應(yīng)的行為,可以有一個或者多個行為。
- 具體狀態(tài)角色(ConcreteState):具體實現(xiàn)該狀態(tài)對應(yīng)的行為,并且在需要的情況下實現(xiàn)狀態(tài)的切換。
狀態(tài)模式與責任鏈模式
看這個狀態(tài)模式的實現(xiàn)是有點和責任鏈模式相似,都是一條鏈去處理,可以這么說在某種場景下這兩種模式可以互相替換,但是這兩種模式也是有本質(zhì)區(qū)別的。
- 狀態(tài)模式:
狀態(tài)模式的下一個節(jié)點是各個狀態(tài)對象已經(jīng)了解的,而且狀態(tài)的流轉(zhuǎn)就是由內(nèi)部進行流轉(zhuǎn),客戶端無法決定。 - 責任鏈模式
“鏈路”上的對象并不知道下一個節(jié)點處理人是誰,而是由客戶端自行組裝決定的。
狀態(tài)模式與策略模式
狀態(tài)模式和策略模式都能用來消除大量的if/else場景,但是也有本質(zhì)區(qū)別。策略模式中各個策略之間是獨立的,相互可以替換的,任意選擇其中一個策略就能滿足需求,而且是由客戶端自己做出選擇。而狀態(tài)模式客戶端只能選擇初始節(jié)點,后續(xù)就會自動流轉(zhuǎn),各個狀態(tài)是一個整體,不存在可以互相替換的狀態(tài)。
狀態(tài)模式應(yīng)用場景
當控制一個對象狀態(tài)的條件表達式過于復雜的時候,就可以考慮使用狀態(tài)模式,通過把狀態(tài)的判斷邏輯轉(zhuǎn)移到表示不同狀態(tài)的一系列類中,這樣就可以把復雜的邏輯簡單化,使得對象的行為依賴于它的狀態(tài),并且會隨著狀態(tài)的改變而同時改變行為。
狀態(tài)模式主要應(yīng)用于以下場景:
- 1、對象的行為需要隨著狀態(tài)的改變而改變時。
- 2、當我們一個操作中需要根據(jù)狀態(tài)來寫大量的if/else邏輯時
狀態(tài)模式優(yōu)缺點
優(yōu)點:
- 1、通過將每個狀態(tài)設(shè)置為獨立的對象,消除了代碼中存在的大量if/else等判斷分支,使得代碼更加簡潔,更容易維護。
- 2、將不同的狀態(tài)通過不同的類來表示,使得狀態(tài)切換時相比較于用數(shù)字或者字符串來表示時更加直觀,轉(zhuǎn)換目的也更加明確。
- 3、每個狀態(tài)類的職責單一明確,易于擴展。
缺點
- 1、狀態(tài)過多會引起類膨脹(事實上這也是大部分設(shè)計模式的通病)。
- 2、狀態(tài)模式的結(jié)構(gòu)與實現(xiàn)相對較為復雜,容易造成代碼混亂。
- 3、對于支持狀態(tài)切換的狀態(tài)類違反了開閉原則,因為一旦狀態(tài)修改或者中間要新增狀態(tài),則需要修改對應(yīng)的源代碼,否則會出現(xiàn)狀態(tài)切換錯誤。
總結(jié)
本文主要介紹了狀態(tài)模式的定義,并通過一個簡單的示例來實現(xiàn)了一個簡單的狀態(tài)模式,最后將狀態(tài)模式和責任鏈模式進行了對比分析,明確了其和策略模式,責任鏈模式的區(qū)別。
請關(guān)注我,和孤狼一起學習進步。
總結(jié)
以上是生活随笔為你收集整理的【设计模式系列19】状态模式原理分析及其和策略模式,责任链模式的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux icmp 时间戳过滤,ICM
- 下一篇: asp.net ajax控件工具集 Au