成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

設(shè)計模式之狀態(tài)模式

zhangke3016 / 1340人閱讀

摘要:為了實現(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)

具體代碼實現(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é)果


五、優(yōu)缺點 1、優(yōu)點

(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

相關(guān)文章

  • 設(shè)計模式手冊狀態(tài)模式

    摘要:什么是狀態(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地址 博...

    call_me_R 評論0 收藏0
  • 設(shè)計模式手冊狀態(tài)模式

    摘要:什么是狀態(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地址 博...

    Faremax 評論0 收藏0
  • 設(shè)計模式享元模式

    摘要:而享元模式的核心就是運用共享技術(shù)來有效支持大量細(xì)粒度的對象。享元模式要求將對象的屬性劃分為內(nèi)部狀態(tài)和外部狀態(tài),所以在了解享元模式之前我們先要了解兩個概念內(nèi)部狀態(tài)外部狀態(tài)。一般情況下在這四種情況下應(yīng)該考慮使用享元模式。 享元模式(flyweight)是一種用于性能優(yōu)化的模式,之所以用fly其意為蠅量級。而享元模式的核心就是運用共享技術(shù)來有效支持大量細(xì)粒度的對象。雖然面向?qū)ο罂梢苑浅7奖愕?..

    Jioby 評論0 收藏0
  • 設(shè)計模式享元模式

    摘要:類圖相關(guān)的設(shè)計模式享元模式和代理模式當(dāng)代理模式消耗性能比較大的時候,就可以用享元模式享元模式和單例模式容器單例,享元模式就是復(fù)用對象的思想。源碼中的享元模式源碼地址享元模式參考慕課網(wǎng)設(shè)計模式精講設(shè)計模式讀書筆記享元模式 0x01.定義與類型 定義:提供了減少對象數(shù)量從而改善應(yīng)用所需的對象結(jié)構(gòu)的方法,系統(tǒng)使用少量對象,而且這些都比較相似,狀態(tài)變化小,可以實現(xiàn)對象的多次復(fù)用。 運用共享技...

    vvpale 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<