国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

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

這篇具有很好參考價(jià)值的文章主要介紹了Gof23設(shè)計(jì)模式之狀態(tài)模式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1.概述

【例】通過(guò)按鈕來(lái)控制一個(gè)電梯的狀態(tài),一個(gè)電梯有開(kāi)門(mén)狀態(tài),關(guān)門(mén)狀態(tài),停止?fàn)顟B(tài),運(yùn)行狀態(tài)。每一種狀態(tài)改變,都有可能要根據(jù)其他狀態(tài)來(lái)更新處理。例如,如果電梯門(mén)現(xiàn)在處于運(yùn)行時(shí)狀態(tài),就不能進(jìn)行開(kāi)門(mén)操作,而如果電梯門(mén)是停止?fàn)顟B(tài),就可以執(zhí)行開(kāi)門(mén)操作。

public interface ILift {
    //電梯的4個(gè)狀態(tài)
    //開(kāi)門(mén)狀態(tài)
    public final static int OPENING_STATE = 1;
    //關(guān)門(mén)狀態(tài)
    public final static int CLOSING_STATE = 2;
    //運(yùn)行狀態(tài)
    public final static int RUNNING_STATE = 3;
    //停止?fàn)顟B(tài)
    public final static int STOPPING_STATE = 4;

    //設(shè)置電梯的狀態(tài)
    public void setState(int state);

    //電梯的動(dòng)作
    public void open();
    public void close();
    public void run();
    public void stop();
}

public class Lift implements ILift {
    private int state;

    @Override
    public void setState(int state) {
        this.state = state;
    }

    //執(zhí)行關(guān)門(mén)動(dòng)作
    @Override
    public void close() {
        switch (this.state) {
            case OPENING_STATE:
                System.out.println("電梯關(guān)門(mén)了。。。");//只有開(kāi)門(mén)狀態(tài)可以關(guān)閉電梯門(mén),可以對(duì)應(yīng)電梯狀態(tài)表來(lái)看
                this.setState(CLOSING_STATE);//關(guān)門(mén)之后電梯就是關(guān)閉狀態(tài)了
                break;
            case CLOSING_STATE:
                //do nothing //已經(jīng)是關(guān)門(mén)狀態(tài),不能關(guān)門(mén)
                break;
            case RUNNING_STATE:
                //do nothing //運(yùn)行時(shí)電梯門(mén)是關(guān)著的,不能關(guān)門(mén)
                break;
            case STOPPING_STATE:
                //do nothing //停止時(shí)電梯也是關(guān)著的,不能關(guān)門(mén)
                break;
        }
    }

    //執(zhí)行開(kāi)門(mén)動(dòng)作
    @Override
    public void open() {
        switch (this.state) {
            case OPENING_STATE://門(mén)已經(jīng)開(kāi)了,不能再開(kāi)門(mén)了
                //do nothing
                break;
            case CLOSING_STATE://關(guān)門(mén)狀態(tài),門(mén)打開(kāi):
                System.out.println("電梯門(mén)打開(kāi)了。。。");
                this.setState(OPENING_STATE);
                break;
            case RUNNING_STATE:
                //do nothing 運(yùn)行時(shí)電梯不能開(kāi)門(mén)
                break;
            case STOPPING_STATE:
                System.out.println("電梯門(mén)開(kāi)了。。。");//電梯停了,可以開(kāi)門(mén)了
                this.setState(OPENING_STATE);
                break;
        }
    }

    //執(zhí)行運(yùn)行動(dòng)作
    @Override
    public void run() {
        switch (this.state) {
            case OPENING_STATE://電梯不能開(kāi)著門(mén)就走
                //do nothing
                break;
            case CLOSING_STATE://門(mén)關(guān)了,可以運(yùn)行了
                System.out.println("電梯開(kāi)始運(yùn)行了。。。");
                this.setState(RUNNING_STATE);//現(xiàn)在是運(yùn)行狀態(tài)
                break;
            case RUNNING_STATE:
                //do nothing 已經(jīng)是運(yùn)行狀態(tài)了
                break;
            case STOPPING_STATE:
                System.out.println("電梯開(kāi)始運(yùn)行了。。。");
                this.setState(RUNNING_STATE);
                break;
        }
    }

    //執(zhí)行停止動(dòng)作
    @Override
    public void stop() {
        switch (this.state) {
            case OPENING_STATE: //開(kāi)門(mén)的電梯已經(jīng)是是停止的了(正常情況下)
                //do nothing
                break;
            case CLOSING_STATE://關(guān)門(mén)時(shí)才可以停止
                System.out.println("電梯停止了。。。");
                this.setState(STOPPING_STATE);
                break;
            case RUNNING_STATE://運(yùn)行時(shí)當(dāng)然可以停止了
                System.out.println("電梯停止了。。。");
                this.setState(STOPPING_STATE);
                break;
            case STOPPING_STATE:
                //do nothing
                break;
        }
    }
}

public class Client {
    public static void main(String[] args) {
        Lift lift = new Lift();
        lift.setState(ILift.STOPPING_STATE);//電梯是停止的
        lift.open();//開(kāi)門(mén)
        lift.close();//關(guān)門(mén)
        lift.run();//運(yùn)行
        lift.stop();//停止
    }
}

問(wèn)題分析:

  • 使用了大量的switch…case這樣的判斷(if…else也是一樣),使程序的可閱讀性變差。
  • 擴(kuò)展性很差。如果新加了斷電的狀態(tài),我們需要修改上面判斷邏輯

定義:

對(duì)有狀態(tài)的對(duì)象,把復(fù)雜的“判斷邏輯”提取到不同的狀態(tài)對(duì)象中,允許狀態(tài)對(duì)象在其內(nèi)部狀態(tài)發(fā)生改變時(shí)改變其行為。

2.結(jié)構(gòu)

狀態(tài)模式包含以下主要角色。

  • 環(huán)境(Context)角色:也稱為上下文,它定義了客戶程序需要的接口,維護(hù)一個(gè)當(dāng)前狀態(tài),并將與狀態(tài)相關(guān)的操作委托給當(dāng)前狀態(tài)對(duì)象來(lái)處理。
  • 抽象狀態(tài)(State)角色:定義一個(gè)接口,用以封裝環(huán)境對(duì)象中的特定狀態(tài)所對(duì)應(yīng)的行為。
  • 具體狀態(tài)(Concrete State)角色:實(shí)現(xiàn)抽象狀態(tài)所對(duì)應(yīng)的行為。

3.案例實(shí)現(xiàn)

/**
 * @author 曉風(fēng)殘?jiān)翷x
 * @date 2023/7/29 14:57
 *      抽象狀態(tài)類(lèi)
 */
public abstract class LiftState {

    // 聲明環(huán)境角色類(lèi)變量
    protected Context context;

    public void setContext(Context context) {
        this.context = context;
    }

    public Context getContext() {
        return context;
    }

    // 電梯開(kāi)啟操作
    public abstract void open();

    // 電梯關(guān)閉操作
    public abstract void close();

    // 電梯運(yùn)行操作
    public abstract void run();

    // 電梯停止操作
    public abstract void stop();

}


/**
 * @author 曉風(fēng)殘?jiān)翷x
 * @date 2023/7/29 15:00
 *      電梯開(kāi)啟狀態(tài)類(lèi)
 */
public class OpeningState extends LiftState {
    //開(kāi)啟當(dāng)然可以關(guān)閉了,我就想測(cè)試一下電梯門(mén)開(kāi)關(guān)功能
    @Override
    public void open() {
        System.out.println("電梯門(mén)開(kāi)啟...");
    }

    @Override
    public void close() {
        //狀態(tài)修改
        super.context.setLiftState(Context.CLOSING_STATE);
        //動(dòng)作委托為CloseState來(lái)執(zhí)行,也就是委托給了ClosingState子類(lèi)執(zhí)行這個(gè)動(dòng)作
        super.context.getLiftState().close();
    }

    //電梯門(mén)不能開(kāi)著就跑,這里什么也不做
    @Override
    public void run() {
        //do nothing
    }

    //開(kāi)門(mén)狀態(tài)已經(jīng)是停止的了
    @Override
    public void stop() {
        //do nothing
    }
}


/**
 * @author 曉風(fēng)殘?jiān)翷x
 * @date 2023/7/29 15:00
 *      電梯運(yùn)行狀態(tài)類(lèi)
 */
public class RunningState extends LiftState {
    //運(yùn)行的時(shí)候開(kāi)電梯門(mén)?你瘋了!電梯不會(huì)給你開(kāi)的
    @Override
    public void open() {
        //do nothing
    }

    //電梯門(mén)關(guān)閉?這是肯定了
    @Override
    public void close() {//雖然可以關(guān)門(mén),但這個(gè)動(dòng)作不歸我執(zhí)行
        //do nothing
    }

    //這是在運(yùn)行狀態(tài)下要實(shí)現(xiàn)的方法
    @Override
    public void run() {
        System.out.println("電梯正在運(yùn)行...");
    }

    //這個(gè)事絕對(duì)是合理的,光運(yùn)行不停止還有誰(shuí)敢做這個(gè)電梯?!估計(jì)只有上帝了
    @Override
    public void stop() {
        super.context.setLiftState(Context.STOPPING_STATE);
        super.context.stop();
    }
}

/**
 * @author 曉風(fēng)殘?jiān)翷x
 * @date 2023/7/29 15:00
 *      電梯停止?fàn)顟B(tài)類(lèi)
 */
public class StoppingState extends LiftState {
    //停止?fàn)顟B(tài),開(kāi)門(mén),那是要的!
    @Override
    public void open() {
        //狀態(tài)修改
        super.context.setLiftState(Context.OPENING_STATE);
        //動(dòng)作委托為CloseState來(lái)執(zhí)行,也就是委托給了ClosingState子類(lèi)執(zhí)行這個(gè)動(dòng)作
        super.context.getLiftState().open();
    }

    @Override
    public void close() {//雖然可以關(guān)門(mén),但這個(gè)動(dòng)作不歸我執(zhí)行
        //狀態(tài)修改
        super.context.setLiftState(Context.CLOSING_STATE);
        //動(dòng)作委托為CloseState來(lái)執(zhí)行,也就是委托給了ClosingState子類(lèi)執(zhí)行這個(gè)動(dòng)作
        super.context.getLiftState().close();
    }

    //停止?fàn)顟B(tài)再跑起來(lái),正常的很
    @Override
    public void run() {
        //狀態(tài)修改
        super.context.setLiftState(Context.RUNNING_STATE);
        //動(dòng)作委托為CloseState來(lái)執(zhí)行,也就是委托給了ClosingState子類(lèi)執(zhí)行這個(gè)動(dòng)作
        super.context.getLiftState().run();
    }

    //停止?fàn)顟B(tài)是怎么發(fā)生的呢?當(dāng)然是停止方法執(zhí)行了
    @Override
    public void stop() {
        System.out.println("電梯停止了...");
    }
}

/**
 * @author 曉風(fēng)殘?jiān)翷x
 * @date 2023/7/29 15:00
 *      電梯關(guān)閉狀態(tài)類(lèi)
 */
public class ClosingState extends LiftState {
    @Override
    //電梯門(mén)關(guān)閉,這是關(guān)閉狀態(tài)要實(shí)現(xiàn)的動(dòng)作
    public void close() {
        System.out.println("電梯門(mén)關(guān)閉...");
    }

    //電梯門(mén)關(guān)了再打開(kāi),逗你玩呢,那這個(gè)允許呀
    @Override
    public void open() {
        super.context.setLiftState(Context.OPENING_STATE);
        super.context.open();
    }


    //電梯門(mén)關(guān)了就跑,這是再正常不過(guò)了
    @Override
    public void run() {
        super.context.setLiftState(Context.RUNNING_STATE);
        super.context.run();
    }

    //電梯門(mén)關(guān)著,我就不按樓層
    @Override
    public void stop() {
        super.context.setLiftState(Context.STOPPING_STATE);
        super.context.stop();
    }
}

/**
 * @author 曉風(fēng)殘?jiān)翷x
 * @date 2023/7/29 14:58
 *      環(huán)境角色類(lèi)
 */
public class Context {

    // 定義對(duì)應(yīng)狀態(tài)對(duì)象的常量
    public final static OpeningState OPENING_STATE = new OpeningState();
    public final static RunningState RUNNING_STATE = new RunningState();
    public final static ClosingState CLOSING_STATE = new ClosingState();
    public final static StoppingState STOPPING_STATE = new StoppingState();

    // 定義一個(gè)當(dāng)前電梯狀態(tài)變量
    private LiftState liftState;

    // 設(shè)置當(dāng)前狀態(tài)對(duì)象
    public void setLiftState(LiftState liftState) {
        this.liftState = liftState;
        // 設(shè)置當(dāng)前狀態(tài)對(duì)象中的Context對(duì)象
        this.liftState.setContext(this);
    }

    public LiftState getLiftState() {
        return liftState;
    }

    public void open() {
        this.liftState.open();
    }

    public void close() {
        this.liftState.close();
    }

    public void stop() {
        this.liftState.stop();
    }

    public void run() {
        this.liftState.run();
    }

}

//測(cè)試類(lèi)
public class Client {
    public static void main(String[] args) {
        Context context = new Context();
        context.setLiftState(new RunningState());

        context.open();
        context.close();
        context.run();
        context.stop();
    }
}

4.優(yōu)缺點(diǎn)

1.優(yōu)點(diǎn):

  • 將所有與某個(gè)狀態(tài)有關(guān)的行為放到一個(gè)類(lèi)中,并且可以方便地增加新的狀態(tài),只需要改變對(duì)象狀態(tài)即可改變對(duì)象的行為。
  • 允許狀態(tài)轉(zhuǎn)換邏輯與狀態(tài)對(duì)象合成一體,而不是某一個(gè)巨大的條件語(yǔ)句塊。

2.缺點(diǎn):文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-732157.html

  • 狀態(tài)模式的使用必然會(huì)增加系統(tǒng)類(lèi)和對(duì)象的個(gè)數(shù)。
  • 狀態(tài)模式的結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂。
  • 狀態(tài)模式對(duì)"開(kāi)閉原則"的支持并不太好。

5.使用場(chǎng)景

  • 當(dāng)一個(gè)對(duì)象的行為取決于它的狀態(tài),并且它必須在運(yùn)行時(shí)根據(jù)狀態(tài)改變它的行為時(shí),就可以考慮使用狀態(tài)模式。
  • 一個(gè)操作中含有龐大的分支結(jié)構(gòu),并且這些分支決定于對(duì)象的狀態(tài)時(shí)。

到了這里,關(guān)于Gof23設(shè)計(jì)模式之狀態(tài)模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Gof23設(shè)計(jì)模式之建造者模式

    建造者模式(Builder Pattern)又叫生成器模式,是一種對(duì)象構(gòu)建模式。它可以將復(fù)雜對(duì)象的建造過(guò)程抽象出來(lái)(抽象類(lèi)別),使這個(gè)抽象過(guò)程的不同實(shí)現(xiàn)方法可以構(gòu)造出不同表現(xiàn)(屬性)的對(duì)象。 建造者模式是一步一步創(chuàng)建一個(gè)復(fù)雜的對(duì)象,它允許用戶只通過(guò)指定復(fù)雜對(duì)象的類(lèi)型和

    2024年02月11日
    瀏覽(34)
  • Gof23設(shè)計(jì)模式之模板方法模式

    定義一個(gè)操作中的算法骨架,而將算法的一些步驟延遲到子類(lèi)中,使得子類(lèi)可以不改變?cè)撍惴ńY(jié)構(gòu)的情況下重定義該算法的某些特定步驟。 模板方法(Template Method)模式包含以下主要角色: 抽象類(lèi)(Abstract Class):負(fù)責(zé)給出一個(gè)算法的輪廓和骨架。它由一個(gè)模板方法和若干個(gè)

    2024年02月13日
    瀏覽(20)
  • Gof23設(shè)計(jì)模式之責(zé)任鏈模式

    責(zé)任鏈模式又名職責(zé)鏈模式,為了避免請(qǐng)求發(fā)送者與多個(gè)請(qǐng)求處理者耦合在一起,將所有請(qǐng)求的處理者通過(guò)前一對(duì)象記住其下一個(gè)對(duì)象的引用而連成一條鏈;當(dāng)有請(qǐng)求發(fā)生時(shí),可將請(qǐng)求沿著這條鏈傳遞,直到有對(duì)象處理它為止。 職責(zé)鏈模式主要包含以下角色: 抽象處理者(

    2024年02月09日
    瀏覽(25)
  • Gof23設(shè)計(jì)模式之橋接外觀模式

    又名門(mén)面模式,是一種通過(guò)為多個(gè)復(fù)雜的子系統(tǒng)提供一個(gè)一致的接口,而使這些子系統(tǒng)更加容易被訪問(wèn)的模式。該模式對(duì)外有一個(gè)統(tǒng)一接口,外部應(yīng)用程序不用關(guān)心內(nèi)部子系統(tǒng)的具體的細(xì)節(jié),這樣會(huì)大大降低應(yīng)用程序的復(fù)雜度,提高了程序的可維護(hù)性。 外觀(Facade)模式包含

    2024年02月15日
    瀏覽(22)
  • Gof23設(shè)計(jì)模式之單例模式(完整)

    單例模式(Singleton pattern)是Java中最簡(jiǎn)單的設(shè)計(jì)模式之一。這種設(shè)計(jì)模式屬于創(chuàng)建型模型,它提供了一種創(chuàng)建對(duì)象的最佳方式。 這種模式涉及到一個(gè)單一的類(lèi),該類(lèi)負(fù)責(zé)創(chuàng)建自己的對(duì)象,同時(shí)確保只有單個(gè)對(duì)象被創(chuàng)建。這個(gè)類(lèi)提供了一種訪問(wèn)其唯一的對(duì)象的方式,可以直接訪

    2024年02月10日
    瀏覽(26)
  • GOF 23 種設(shè)計(jì)模式應(yīng)用場(chǎng)景分析

    本文看下GOF 23 種設(shè)計(jì)模式應(yīng)用場(chǎng)景,詳細(xì)的還是通過(guò)文章給出參考鏈接學(xué)習(xí)下。 參考這篇文章 。 有幾種產(chǎn)品需要?jiǎng)?chuàng)建,比如創(chuàng)建紅蘋(píng)果,青蘋(píng)果,綠蘋(píng)果,這些對(duì)象通過(guò)一個(gè)對(duì)象就可以。 參考這篇文章 。 有幾種產(chǎn)品需要?jiǎng)?chuàng)建,但是每種產(chǎn)品不能簡(jiǎn)單的通過(guò)一個(gè)對(duì)象來(lái)表示

    2024年02月16日
    瀏覽(28)
  • 創(chuàng)建型模式 (Creational Patterns) 玄子Share 設(shè)計(jì)模式 GOF 全23種 + 七大設(shè)計(jì)原則

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-NWLAOFtO-1691793071647)(./assets/%E7%8E%84%E5%AD%90Share%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20GOF%20%E5%85%A823%E7%A7%8D%20+%20%E4%B8%83%E5%A4%A7%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99.png)] GoF(Gang of Four)是四位計(jì)算機(jī)科學(xué)家(Erich Gamma、Ri

    2024年02月12日
    瀏覽(28)
  • java 23種設(shè)計(jì)模式

    java 23種設(shè)計(jì)模式

    1、創(chuàng)建型模式(Creational Patterns) 2、結(jié)構(gòu)型模式(Structural Patterns) 3、行為型模式(Behavioral Patterns) 創(chuàng)建型模式(Creational Patterns): ? ? ? ? 1、工廠方法模式(Factory Method Pattern) ? ? ? ? ? ? ? 1.1、簡(jiǎn)單工廠模式(Simple Factory Pattern) ? ? ? ? 2、抽象工廠模式(Abstract

    2024年01月22日
    瀏覽(26)
  • Java23種設(shè)計(jì)模式之【單例模式】

    Java23種設(shè)計(jì)模式之【單例模式】

    目錄 一.單例模式的起源,和應(yīng)用場(chǎng)景 1.單例模式的前世今生! ?2.什么是單例模式? 2.1使用單例模式的注意事項(xiàng) 2.2如何理解單例模式? 2.3單例模式的優(yōu)勢(shì)以及不足! 2.4使用場(chǎng)景 二.實(shí)現(xiàn) 1.實(shí)現(xiàn)思路 1.1創(chuàng)建一個(gè) Singleton 類(lèi) (SingleObject.java) 1.2從 singleton 類(lèi)獲取唯一的對(duì)象 (Sing

    2024年02月10日
    瀏覽(33)
  • JAVA 23種設(shè)計(jì)模式示例

    JAVA 23種設(shè)計(jì)模式示例

    目錄 一.單例模式 二.工廠方法模式 三.抽象工廠模式 四.建造者模式 五.原型模式 六.享元模式 七.門(mén)面模式 八.適配器模式 九.裝飾者模式 十.策略模式 十一.模板方法模式 十二.觀察者模式 十三.責(zé)任鏈模式 十四.代理模式 十五.橋接模式 十六.組合模式 十七.命令模式 十八.狀態(tài)

    2024年02月13日
    瀏覽(26)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包