狀態(tài)模式

一、模式簡(jiǎn)介

定義:對(duì)有狀態(tài)的對(duì)象,把復(fù)雜的“判斷邏輯”提取到不同的狀態(tài)對(duì)象中,允許狀態(tài)對(duì)象在其內(nèi)部狀態(tài)發(fā)生改變時(shí)改變其行為。
場(chǎng)景:當(dāng)一個(gè)對(duì)象的行為取決于它的狀態(tài),并且它必須在運(yùn)行時(shí)根據(jù)狀態(tài)改變它的行為時(shí)。當(dāng)一個(gè)操作中含有龐大的分支結(jié)構(gòu),并且這些分支決定于對(duì)象的狀態(tài)時(shí)。

  • 角色結(jié)構(gòu):
  • 環(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)的行為。

二、模式實(shí)現(xiàn)

public abstract class AbstractThreadState { -> 抽象狀態(tài)
    protected String state;
    protected abstract String state();
}

public class NewConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
    public void start(ThreadContext context){
        if("new".equals(context.getState().state())){
            System.out.println("線程處于new狀態(tài),切換到runnable狀態(tài)");
            context.setState(new RunnableConcreteThreadState());
        }else{
            System.out.println("線程不處于new狀態(tài),不能調(diào)用start方法");
        }
    }

    @Override
    protected String state() {
        super.state = "new";
        return this.state;
    }
}

public class RunnableConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
    @Override
    protected String state() {
        super.state = "runnable";
        return this.state;
    }

    public void cpu(ThreadContext context){
        if("runnable".equals(context.getState().state())){
            System.out.println("線程處于runnable狀態(tài),切換到running狀態(tài)");
            context.setState(new RunningConcreteThreadState());
        }else{
            System.out.println("線程不處于runnable狀態(tài),不能調(diào)用cpu方法");
        }
    }
}

public class RunningConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
    @Override
    protected String state() {
        super.state = "running";
        return this.state;
    }

    public void suspend(ThreadContext context){
        if("running".equals(context.getState().state())){
            context.setState(new BlockConcreteThreadState());
            System.out.println("線程處于runnable狀態(tài),切換到block狀態(tài)");
        }else{
            System.out.println("線程不處于runnable狀態(tài),不能調(diào)用suspend方法");
        }
    }

    public void stop(ThreadContext context){
        if("running".equals(context.getState().state())){
            context.setState(new DeadConcreteThreadState());
            System.out.println("線程處于runnable狀態(tài),切換到deal狀態(tài)");
        }else{
            System.out.println("線程不處于runnable狀態(tài),不能調(diào)用stop方法");
        }
    }
}

public class BlockConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
    @Override
    protected String state() {
        super.state = "block";
        return this.state;
    }

    public void resume(ThreadContext context){
        if("block".equals(context.getState().state())){
            System.out.println("線程處于block狀態(tài),切換到runnable狀態(tài)");
            context.setState(new RunningConcreteThreadState());
        }else{
            System.out.println("線程不處于block狀態(tài),不能調(diào)用resume方法");
        }
    }
}

public class DeadConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
    @Override
    protected String state() {
        super.state = "deal";
        return this.state;
    }

    public void dead(){
        System.out.println("線程處于deal狀態(tài)");
    }
}

public class ThreadContext { -> 環(huán)境
    private AbstractThreadState state;

    public ThreadContext(AbstractThreadState state) {
        this.state = state;
    }

    public void start() {
        if(state instanceof NewConcreteThreadState){
            ((NewConcreteThreadState) state).start(this);
        }else{
            System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法start");
        }
    }

    public void cpu() {
        if(state instanceof RunnableConcreteThreadState){
            ((RunnableConcreteThreadState) state).cpu(this);
        }else{
            System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法cpu");
        }
    }

    public void stop() {
        if(state instanceof RunningConcreteThreadState){
            ((RunningConcreteThreadState) state).stop(this);
        }else{
            System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法stop");
        }
    }

    public void suspend() {
        if(state instanceof RunningConcreteThreadState){
            ((RunningConcreteThreadState) state).suspend(this);
        }else{
            System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法suspend");
        }
    }

    public void resume() {
        if(state instanceof BlockConcreteThreadState){
            ((BlockConcreteThreadState) state).resume(this);
        }else{
            System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法resume");
        }
    }

    public AbstractThreadState getState() {
        return state;
    }

    public void setState(AbstractThreadState state) {
        this.state = state;
    }
}

以Java線程狀態(tài)切換為例子,狀態(tài)包含new、runnable、running、block、dead,每種狀態(tài)有各自的行為,當(dāng)調(diào)用者與線程對(duì)象產(chǎn)生互動(dòng)后,線程對(duì)象內(nèi)部的狀態(tài)隨之發(fā)生改變,線程對(duì)象的行為同時(shí)發(fā)生改變。

ThreadContext context=new ThreadContext(new NewConcreteThreadState());
context.start();
context.cpu();
context.suspend();
context.resume();
context.cpu();
context.stop();
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 點(diǎn)贊再看,養(yǎng)成習(xí)慣,公眾號(hào)搜一搜【一角錢技術(shù)[https://p3-juejin.byteimg.com/tos-...
    一角錢技術(shù)閱讀 540評(píng)論 2 9
  • 在軟件開發(fā)過程中,應(yīng)用程序中的有些對(duì)象可能會(huì)根據(jù)不同的情況做出不同的行為,我們把這種對(duì)象稱為有狀態(tài)的對(duì)象,而把影響...
    兜兜_2925閱讀 350評(píng)論 0 1
  • 在軟件開發(fā)過程中,應(yīng)用程序中的有些對(duì)象可能會(huì)根據(jù)不同的情況做出不同的行為,我們把這種對(duì)象稱為有狀態(tài)的對(duì)象,而把影響...
    迷心迷閱讀 348評(píng)論 0 1
  • 在軟件開發(fā)過程中,應(yīng)用程序中的有些對(duì)象可能會(huì)根據(jù)不同的情況做出不同的行為,我們把這種對(duì)象稱為有狀態(tài)的對(duì)象,而把影響...
    Zal哥哥閱讀 762評(píng)論 0 0
  • 狀態(tài)模式(State) 在軟件開發(fā)過程中,應(yīng)用程序中的有些對(duì)象可能會(huì)根據(jù)不同的情況做出不同的行為,我們把這種對(duì)象稱...
    Acton_zhang閱讀 338評(píng)論 0 1

友情鏈接更多精彩內(nèi)容