摘要:為了實現(xiàn)這個正義偷笑又合理的訴求,你得先學(xué)會今天要介紹的設(shè)計模式,因為你們公司的這個流程可能就是用今天這個模式設(shè)計的。狀態(tài)模式對開閉原則的支持并不太好,新增狀態(tài)時,不僅得增加狀態(tài)類,還得修改原來已經(jīng)有的狀態(tài),讓之前的狀態(tài)切換到新增的狀態(tài)。
一、定義你是否經(jīng)常請(偷)假(懶)?是不是對公司萬惡的請假申請流程深惡痛絕。有沒有想過偷偷改造這個萬惡的系統(tǒng),從 申請->項目經(jīng)理審批->部門審批->老板審批->完成? 偷偷改為? 申請->完成。為了實現(xiàn)這個正義[偷笑]又合理的訴求,你得先學(xué)會今天要介紹的設(shè)計模式,因為你們公司的這個流程可能就是用今天這個模式設(shè)計的。來看看這個設(shè)計模式是怎么來抽象這類流程性的業(yè)務(wù)的。
狀態(tài)模式【百度百科】:當(dāng)一個對象的內(nèi)在狀態(tài)改變時允許改變其行為,這個對象看起來像是改變了其類。
這個定義看起來莫名其妙,咋一看,我也不知道它要表達(dá)什么。個人的理解:某個對象是有狀態(tài)的,比如我們上面的請假流程,它處于項目經(jīng)理狀態(tài),那項目經(jīng)理可以審核你的請假申請,到了老板處理環(huán)節(jié),老板直接把你申請單刪了【哈哈】。在這不同的狀態(tài)是可以有不同的操作的。不知道你看懂了定義了沒??什么?沒看懂,那就直接看下面的代碼咯,talk is cheap show me the code。
二、UML圖
UML圖如下,我直接把請假這個例子畫了個UML圖,如下,有一個公共的State抽象類,里面定義了兩個變量來保存當(dāng)前狀態(tài)的狀態(tài)Code,狀態(tài)Name,下面為具體的狀態(tài),分別為:AppState(申請狀態(tài)),ProjectManagesState(項目經(jīng)理審核狀態(tài)),BossState(老板審核狀態(tài)),通過Context來提供給客戶端使用。
具體代碼實現(xiàn)如下:
1、狀態(tài)抽象類
package com.design.state;
public abstract class State {
private String stateCode;
private String stateName;
//往下個環(huán)節(jié)走
public abstract void toNextState(Context context);
public State(String stateCode, String stateName){
this.stateCode = stateCode;
this.stateName = stateName;
}
public String getStateCode() {
return stateCode;
}
public void setStateCode(String stateCode) {
this.stateCode = stateCode;
}
public String getStateName() {
return stateName;
}
public void setStateName(String stateName) {
this.stateName = stateName;
}
}
2、定義具體的狀態(tài)
package com.design.state;
/**
* 申請狀態(tài)
*/
public class AppState extends State{
public AppState(){
super("Apply", "申請環(huán)節(jié)");
}
@Override
public void toNextState(Context context) {
//申請狀態(tài),這里可以做該狀態(tài)下的操作
System.out.println("我是申請人,我申請休假,下一個環(huán)節(jié)是項目經(jīng)理審核!!");
//直接進(jìn)去項目經(jīng)理審核狀態(tài)
context.setCurrentState(new ProjectManagesState());
}
}
package com.design.state;
/**
* 項目經(jīng)理審核狀態(tài)
*/
public class ProjectManagesState extends State{
public ProjectManagesState(){
super("ProjectManages", "項目經(jīng)理審核環(huán)節(jié)");
}
@Override
public void toNextState(Context context) {
//項目經(jīng)理審核狀態(tài),這里可以做該狀態(tài)下的操做
System.out.println("我是項目經(jīng)理,那臭小子一定有跑去面試了,哎,幫他一把,同意了,下個環(huán)節(jié)讓老板審去");
//直接進(jìn)去老板審核狀態(tài)
context.setCurrentState(new BossState());
}
}
package com.design.state;
/**
* 老板審核狀態(tài)
*/
public class BossState extends State{
public BossState(){
super("Boss Audit", "老板審核環(huán)節(jié)");
}
@Override
public void toNextState(Context context) {
//項目經(jīng)理審核狀態(tài),這里可以做該狀態(tài)下的操做
System.out.println("我是老板,我同意你請假了!!!流程結(jié)束!");
}
}
3、上下文類
package com.design.state;
public class Context {
private State currentState;
public Context(State state){
currentState = state;
}
public void toNextState(){
currentState.toNextState(this);
};
public State getCurrentState() {
return currentState;
}
public void setCurrentState(State currentState) {
this.currentState = currentState;
}
}
4、寫好了,看下怎么調(diào)用
package com.design.state;
public class TestMain {
public static void main(String[] args) {
//創(chuàng)建申請休假單
Context context = new Context(new AppState());
System.out.println("狀態(tài):"+context.getCurrentState().getStateName());
//提交申請
context.toNextState();
System.out.println("狀態(tài):"+context.getCurrentState().getStateName());
//項目經(jīng)理審核
context.toNextState();
System.out.println("狀態(tài):"+context.getCurrentState().getStateName());
//老板審核
context.toNextState();
}
}
5、執(zhí)行結(jié)果
(1)、將與特定狀態(tài)相關(guān)的行為局部化,將不同狀態(tài)的行為分割開來。
(2)、把狀態(tài)轉(zhuǎn)移邏輯分布到具體狀態(tài)類中,減少相互間的依賴。
看不懂這兩個優(yōu)點??OK,我們來解釋下,先來看看,不用狀態(tài)模式,我們代碼會怎么寫?
package com.design.state;
public class StateChange {
private int state = 0;
private final static int APPLY=0; //申請狀態(tài)
private final static int PROJECTMANAGES=1;//項目經(jīng)理審核狀態(tài)
private final static int BOSS=2;//老板審核狀態(tài)
private final static int FINISH=3;//流程結(jié)束狀態(tài)
public void toNextState(){
switch (state){
case 0:
//申請狀態(tài),做點操作
System.out.println("寫申請書!!!");
//進(jìn)入項目經(jīng)理審核狀態(tài)
state = PROJECTMANAGES;
break;
case 1:
System.out.println("項目經(jīng)理審核,同意你申請了");
//進(jìn)入老板審核狀態(tài)
state = BOSS;
break;
case 2:
System.out.println("我是老板,同意你申請了");
//進(jìn)入結(jié)束狀態(tài)
state = FINISH;
break;
default:
break;
}
}
}
你是不是寫的跟我一樣呢??有沒有注意到,所有的操作,無論是哪個狀態(tài)的操作都是在這個類中完成的,而使用狀態(tài)模式,不同狀態(tài)下的行為是定義在不同的狀態(tài)類下的。這就是前面說的優(yōu)點1。
我們狀態(tài)切換是通過switch來判斷狀態(tài),再決定下一個狀態(tài)的,而在狀態(tài)模式下,切換到下一個狀態(tài),是在具體的狀態(tài)類下進(jìn)行的,可以減少if之類的判斷邏輯。這就是優(yōu)點2。
2、缺點(1)、狀態(tài)模式的結(jié)構(gòu)與實現(xiàn)都較為復(fù)雜,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂。?
(2)、狀態(tài)模式對"開閉原則"的支持并不太好,新增狀態(tài)時,不僅得增加狀態(tài)類,還得修改原來已經(jīng)有的狀態(tài),讓之前的狀態(tài)切換到新增的狀態(tài)。
六、總結(jié)說明狀態(tài)模式將原來通過判斷實現(xiàn)的狀態(tài)切換分散到各具體狀態(tài)類中,比如上面切換到“老板審核狀態(tài)”,是在“項目經(jīng)理審核狀態(tài)”中進(jìn)行的,當(dāng)狀態(tài)比較多的情況,不容易理清各狀態(tài)切換關(guān)系。同時它有將各狀態(tài)的操作獨立到狀態(tài)類中,方便測試,還有分隔開各不同操作,便于閱讀代碼。實際運用中可根據(jù)自己的場景進(jìn)行權(quán)衡。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/7849.html
摘要:什么是狀態(tài)模式狀態(tài)模式對象行為是基于狀態(tài)來改變的。原文地址設(shè)計模式手冊之狀態(tài)模式優(yōu)缺點優(yōu)點封裝了轉(zhuǎn)化規(guī)則,對于大量分支語句,可以考慮使用狀態(tài)類進(jìn)一步封裝。 1. 什么是狀態(tài)模式? 狀態(tài)模式:對象行為是基于狀態(tài)來改變的。 內(nèi)部的狀態(tài)轉(zhuǎn)化,導(dǎo)致了行為表現(xiàn)形式不同。所以,用戶在外面看起來,好像是修改了行為。 Webpack4系列教程(17篇) + 設(shè)計模式手冊(16篇):GitHub地址 博...
摘要:什么是狀態(tài)模式狀態(tài)模式對象行為是基于狀態(tài)來改變的。原文地址設(shè)計模式手冊之狀態(tài)模式優(yōu)缺點優(yōu)點封裝了轉(zhuǎn)化規(guī)則,對于大量分支語句,可以考慮使用狀態(tài)類進(jìn)一步封裝。 1. 什么是狀態(tài)模式? 狀態(tài)模式:對象行為是基于狀態(tài)來改變的。 內(nèi)部的狀態(tài)轉(zhuǎn)化,導(dǎo)致了行為表現(xiàn)形式不同。所以,用戶在外面看起來,好像是修改了行為。 Webpack4系列教程(17篇) + 設(shè)計模式手冊(16篇):GitHub地址 博...
摘要:而享元模式的核心就是運用共享技術(shù)來有效支持大量細(xì)粒度的對象。享元模式要求將對象的屬性劃分為內(nèi)部狀態(tài)和外部狀態(tài),所以在了解享元模式之前我們先要了解兩個概念內(nèi)部狀態(tài)外部狀態(tài)。一般情況下在這四種情況下應(yīng)該考慮使用享元模式。 享元模式(flyweight)是一種用于性能優(yōu)化的模式,之所以用fly其意為蠅量級。而享元模式的核心就是運用共享技術(shù)來有效支持大量細(xì)粒度的對象。雖然面向?qū)ο罂梢苑浅7奖愕?..
摘要:類圖相關(guān)的設(shè)計模式享元模式和代理模式當(dāng)代理模式消耗性能比較大的時候,就可以用享元模式享元模式和單例模式容器單例,享元模式就是復(fù)用對象的思想。源碼中的享元模式源碼地址享元模式參考慕課網(wǎng)設(shè)計模式精講設(shè)計模式讀書筆記享元模式 0x01.定義與類型 定義:提供了減少對象數(shù)量從而改善應(yīng)用所需的對象結(jié)構(gòu)的方法,系統(tǒng)使用少量對象,而且這些都比較相似,狀態(tài)變化小,可以實現(xiàn)對象的多次復(fù)用。 運用共享技...
閱讀 2008·2019-08-29 16:27
閱讀 1379·2019-08-29 16:14
閱讀 3380·2019-08-29 14:18
閱讀 3463·2019-08-29 13:56
閱讀 1261·2019-08-29 11:13
閱讀 2131·2019-08-28 18:19
閱讀 3450·2019-08-27 10:57
閱讀 2287·2019-08-26 11:39