策略模式和工厂模式的区别_java设计模式之状态模式,策略模式孪生兄弟
狀態模式
狀態模式(State Pattern)中,類的行為是基于它的狀態改變的,狀態之間的切換,在狀態A執行完畢后自己控制狀態指向狀態B,狀態模式是不停的切換狀態執行。這種類型的設計模式屬于行為型模式。
狀態模式解決的問題
解決內在狀態的改變而引起行為改變的問題,它的出發點是事物的狀態,封裝狀態而暴露行為,一個對象的狀態改變,從外界來看就好像是行為改變。
狀態模式角色
State: 抽象狀態類,定義一個接口以封裝與context的一個狀態相關的行為
ConcreteState: 具體狀態,每一子類實現一個與Context的一個狀態相關的行為
Context: 狀態上下文,維護一個ConcreteState子類的實例,這個實例定義當前的狀態。
狀態模式抽象類方法類型
上下文抽象方法:request,上下文處理請求。
狀態抽象方法:handle,狀態行為方法,不同的狀態,行為不同。
狀態模式和策略模式的區別
狀態是系統自身的固有的,調用者不能控制系統的狀態轉移。比如,一個請假單有“部長審批”-“經理審批”-“審批通過”-“審批不通過”等狀態,請假者沒有辦法將一個部長都還沒審批完的請假單提交給經理,這個狀態轉換只能系統自己完成。
策略是外界給的,策略怎么變,是調用者考慮的事情,系統只是根據所給的策略做事情。
環境角色的職責不同
兩者都有一個叫做Context環境角色的類,但是兩者的區別很大,策略模式的環境角色只是一個委托作用,負責算法的替換;而狀態模式的環境角色不僅僅是委托行為,它還具有登記狀態變化的功能,與具體的狀態類協作,共同完成狀態切換行為隨之切換的任務。
解決問題的重點不同
策略模式旨在解決內部算法如何改變的問題,也就是將內部算法的改變對外界的影響降低到最小,它保證的是算法可以自由地切換;而狀態模式旨在解決內在狀態的改變而引起行為改變的問題,它的出發點是事物的狀態,封裝狀態而暴露行為,一個對象的狀態改變,從外界來看就好像是行為改變。
解決問題的方法不同
策略模式只是確保算法可以自由切換,但是什么時候用什么算法它決定不了;而狀態模式對外暴露的是行為,狀態的變化一般是由環境角色和具體狀態共同完成的,也就是說狀態模式封裝了狀態的變化而暴露了不同的行為或行為結果。
復雜度不同
通常策略模式比較簡單,這里的簡單指的是結構簡單,擴展比較容易,而且代碼也容易閱讀。狀態模式則通常比較復雜,因為它要從兩個角色看到一個對象狀態和行為的改變,也就是說它封裝的是變化,要知道變化是無窮盡的,因此相對來說狀態模式通常都比較復雜,涉及面很多,雖然也很容易擴展,但是一般不會進行大規模的擴張和修正
代碼實現
銷售員工報銷,需要主管、經理、總監審批,審批通過之后財務打款。
/** * 抽象狀態類 */public abstract class State { protected Context context; public Context getContext() { return context; } public void setContext(Context context) { this.context = context; } public abstract void handle();}/** * 狀態上下文 */public class Context { private State state; public Context() { } public State getState() { return state; } public void setState(State state) { this.state = state; this.state.setContext(this); } public void request(){ this.state.handle(); }}/** * 主管審批狀態 */public class SupervisorState extends State{ public void handle() { System.out.println("主管審批通過,下一個經理審批"); context.setState(new ManagerState()); }}/** * 經理審批狀態 */public class ManagerState extends State{ public void handle() { System.out.println("經理審批通過,下一個總監審批"); context.setState(new DirectorState()); }}/** * 總監審批狀態 */public class DirectorState extends State{ public void handle() { System.out.println("總監審批通過,我是最后一個審批者"); //審核通過之后的邏輯 System.out.println("財務打款500元"); }}/** * 狀態模式測試類 */public class StateModeTest { public static void main(String[] args) { Context context = new Context(); context.setState(new SupervisorState()); context.request(); context.request(); context.request(); }}運行結果:
以上代碼只是為了簡單的展示狀態模式,如果審批工作流是一個復雜的過程,有專門的工作流框架,這里推薦activiti。BPMN:業務流程建模與標注,包括這些圖元如何組合成一個業務流程圖,讓業務工作流更靈活,用戶可以根據自己的業務場景,定義自己特有的流程圖。
優缺點
優點:封裝了轉換規則。枚舉可能的狀態,在枚舉狀態之前需要確定狀態種類。允許狀態轉換邏輯與狀態對象合成一體,而不是某一個巨大的條件語句塊。
缺點:狀態模式的使用必然會增加系統類和對象的個數。狀態模式對"開閉原則"的支持并不太好,對于可以切換狀態的狀態模式,增加新的狀態類需要修改那些負責狀態轉換的代碼。
生活中的狀態模式
審批工作流,報銷審批,銷售發起審批,如果金額小于200,只需要主管審批,如果金額在200-500之間需要經理審批,金額大于500小于2000,需要總監審批,大于2000需要老板審批。每一個審批人審批都對應著狀態的變化。
訂單狀態的變化,下單、待支付、支付、發貨、待收貨、收貨、取消、待退款、已退款等等,每一個訂單背后承載著很多不同的狀態。每一個狀態,都有不一樣的業務邏輯。
我的啟發
狀態模式,策略模式的孿生兄弟,兩者之間極其相似,但是如果我們用心去觀察體會,一定能找出它們之間的不同。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的策略模式和工厂模式的区别_java设计模式之状态模式,策略模式孪生兄弟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10网银控件不兼容(win10网银
- 下一篇: yjv是电缆还是电线_BVV属于电线还是