状态模式

一、模式简介

定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
场景:当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时。当一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。

  • 角色结构:
  • 环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。
  • 具体状态(Concrete State)角色:实现抽象状态所对应的行为。

二、模式实现

public abstract class AbstractThreadState { -> 抽象状态
    protected String state;
    protected abstract String state();
}

public class NewConcreteThreadState extends AbstractThreadState { -> 具体状态
    public void start(ThreadContext context){
        if("new".equals(context.getState().state())){
            System.out.println("线程处于new状态,切换到runnable状态");
            context.setState(new RunnableConcreteThreadState());
        }else{
            System.out.println("线程不处于new状态,不能调用start方法");
        }
    }

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

public class RunnableConcreteThreadState extends AbstractThreadState { -> 具体状态
    @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状态,切换到running状态");
            context.setState(new RunningConcreteThreadState());
        }else{
            System.out.println("线程不处于runnable状态,不能调用cpu方法");
        }
    }
}

public class RunningConcreteThreadState extends AbstractThreadState { -> 具体状态
    @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状态,切换到block状态");
        }else{
            System.out.println("线程不处于runnable状态,不能调用suspend方法");
        }
    }

    public void stop(ThreadContext context){
        if("running".equals(context.getState().state())){
            context.setState(new DeadConcreteThreadState());
            System.out.println("线程处于runnable状态,切换到deal状态");
        }else{
            System.out.println("线程不处于runnable状态,不能调用stop方法");
        }
    }
}

public class BlockConcreteThreadState extends AbstractThreadState { -> 具体状态
    @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状态,切换到runnable状态");
            context.setState(new RunningConcreteThreadState());
        }else{
            System.out.println("线程不处于block状态,不能调用resume方法");
        }
    }
}

public class DeadConcreteThreadState extends AbstractThreadState { -> 具体状态
    @Override
    protected String state() {
        super.state = "deal";
        return this.state;
    }

    public void dead(){
        System.out.println("线程处于deal状态");
    }
}

public class ThreadContext { -> 环境
    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()+"状态,无法start");
        }
    }

    public void cpu() {
        if(state instanceof RunnableConcreteThreadState){
            ((RunnableConcreteThreadState) state).cpu(this);
        }else{
            System.out.println("线程正处于"+state.state()+"状态,无法cpu");
        }
    }

    public void stop() {
        if(state instanceof RunningConcreteThreadState){
            ((RunningConcreteThreadState) state).stop(this);
        }else{
            System.out.println("线程正处于"+state.state()+"状态,无法stop");
        }
    }

    public void suspend() {
        if(state instanceof RunningConcreteThreadState){
            ((RunningConcreteThreadState) state).suspend(this);
        }else{
            System.out.println("线程正处于"+state.state()+"状态,无法suspend");
        }
    }

    public void resume() {
        if(state instanceof BlockConcreteThreadState){
            ((BlockConcreteThreadState) state).resume(this);
        }else{
            System.out.println("线程正处于"+state.state()+"状态,无法resume");
        }
    }

    public AbstractThreadState getState() {
        return state;
    }

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

以Java线程状态切换为例子,状态包含new、runnable、running、block、dead,每种状态有各自的行为,当调用者与线程对象产生互动后,线程对象内部的状态随之发生改变,线程对象的行为同时发生改变。

ThreadContext context=new ThreadContext(new NewConcreteThreadState());
context.start();
context.cpu();
context.suspend();
context.resume();
context.cpu();
context.stop();
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 点赞再看,养成习惯,公众号搜一搜【一角钱技术[https://p3-juejin.byteimg.com/tos-...
    一角钱技术阅读 3,440评论 2 9
  • 在软件开发过程中,应用程序中的有些对象可能会根据不同的情况做出不同的行为,我们把这种对象称为有状态的对象,而把影响...
    兜兜_2925阅读 2,578评论 0 1
  • 在软件开发过程中,应用程序中的有些对象可能会根据不同的情况做出不同的行为,我们把这种对象称为有状态的对象,而把影响...
    迷心迷阅读 2,481评论 0 1
  • 在软件开发过程中,应用程序中的有些对象可能会根据不同的情况做出不同的行为,我们把这种对象称为有状态的对象,而把影响...
    Zal哥哥阅读 4,023评论 0 0
  • 状态模式(State) 在软件开发过程中,应用程序中的有些对象可能会根据不同的情况做出不同的行为,我们把这种对象称...
    Acton_zhang阅读 2,472评论 0 1

友情链接更多精彩内容