状态模式

定义:状态模式也称为状态机模式,是允许对象在内部状态发生改变时改变它的行为,对象看起来好像是修改了它的类。

应用场景:
1. 行为随状态改变而改变的场景
2. 一个操作中含有庞大的多分支结构,并且这些分支取决于对象的状态在实际开发中如电商类项目的订单,审核流程等可以使用状态模式,下面使用电梯来举例状态模式的应用:


/**
 * create by Alan at 2020/3/26 9:35
 * description:抽象电梯状态类
 */
public abstract class LiftState {
    //环境上下文
    protected Context context;

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

    //开门
    public abstract void open();
    //关门
    public abstract void close();
    //启动
    public abstract void run();
    //停止
    public abstract void stop();
}

/**
 * create by Alan at 2020/3/26 9:38
 * description:开门状态
 */
public class OpenningState extends LiftState{
    @Override
    public void open() {
        System.out.println("电梯门开启..");
    }

    @Override
    public void close() {
        //状态修改
        super.context.setLiftState(Context.closingState);
        //动作委托给CloseState来执行
        super.context.getLiftState().close();
    }

    @Override
    public void run() {

    }

    @Override
    public void stop() {

    }
}

/**
 * create by Alan at 2020/3/26 9:38
 * description:关门状态
 */
public class ClosingState extends LiftState{
    @Override
    public void open() {
        //设置为开门状态
        super.context.setLiftState(Context.openningState);
        super.context.getLiftState().open();
    }

    @Override
    public void close() {
        System.out.println("电梯门关闭...");
    }

    @Override
    public void run() {
        super.context.setLiftState(Context.runningState);
        super.context.getLiftState().run();
    }

    @Override
    public void stop() {
        super.context.setLiftState(Context.stopingState);
        super.context.getLiftState().stop();
    }
}

/**
 * create by Alan at 2020/3/26 9:38
 * description:运行状态
 */
public class RunningState extends LiftState{
    @Override
    public void open() {

    }

    @Override
    public void close() {

    }

    @Override
    public void run() {
        System.out.println("电梯在运行中...");
    }

    @Override
    public void stop() {
        super.context.setLiftState(Context.stopingState);
        super.context.getLiftState().stop();
    }
}

/**
 * create by Alan at 2020/3/26 9:38
 * description:停止状态
 */
public class StopingState extends LiftState{
    @Override
    public void open() {
        super.context.setLiftState(Context.openningState);
        super.context.getLiftState().open();
    }

    @Override
    public void close() {

    }

    @Override
    public void run() {
        super.context.setLiftState(Context.runningState);
        super.context.getLiftState().run();
    }

    @Override
    public void stop() {
        System.out.println("电梯停止了...");
    }
}

/**
 * create by Alan at 2020/3/26 9:37
 * description:上下文类
 */
public class Context {
    //定义出所有状态
    public final static OpenningState openningState = new OpenningState();
    public final static ClosingState closingState = new ClosingState();
    public final static RunningState runningState = new RunningState();
    public final static StopingState stopingState = new StopingState();

    //当前电梯状态
    public LiftState liftState;

    public LiftState getLiftState() {
        return liftState;
    }

    public void setLiftState(LiftState liftState) {
        this.liftState = liftState;
        this.liftState.setContext(this);
    }

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

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

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

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

/**
 * create by Alan at 2020/3/26 9:55
 * description:
 */
public class Client {
    public static void main(String[] args) {
        Context context = new Context();
    //设置不同的状态会执行不同操作
        context.setLiftState(new RunningState());
        context.run();
        context.open();
        context.close();
        context.stop();
    }
}

结果:
电梯在运行中...
电梯停止了...

    
上述代码根据当前所处的状态,执行可以运行的事件来扭转状态。


优点:
1. 结构清晰:将状态独立为类,消除了冗余的if...else或switch...case语句,使代码更加简洁,提高系统可维护性
2. 将状态转换显示化:通常的对象内部都是使用数值类型来定义状态,状态的切换是通过赋值今进行表现,不够直观;而使用状态类,在切换状态时,是以不同的类进行表示,转换目的更加明确
3. 状态类职责明确且具备扩展性

缺点:
1. 类膨胀:如果一个事务具备的状态很多,则需要简历很多状态类
2. 状态模式的结构与实现都较为复杂,使用不当会导致程序结构和代码混乱
3. 状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新贼的状态,而且修改某个状态类的行为也需要修改对应类的源代码

Spring中有一个状态机,可以直接使用,目前还没有研究,等研究了在讨论状态机是怎么玩的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值