设计模式(二十)状态模式

作者: 我犟不过你 | 来源:发表于2021-01-25 16:09 被阅读0次

1、概述

状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。

2、使用场景

1)如果对象需要根据自身当前状态进行不同行为, 同时状态的数量非常多且与状态相关的代码会频繁变更的话, 可使用状态模式。
2)如果某个类需要根据成员变量的当前值改变自身行为, 从而需要使用大量的条件语句时, 可使用该模式。
3)当相似状态和基于条件的状态机转换中存在许多重复代码时, 可使用状态模式。

3、实例

有如下场景:

策划一场活动,活动有以下状态:
编辑,保存,提交,审核通过、审核拒绝、关闭、开启

其状态变化如下图所示:

状态.png

创建状态的顶层抽象:

/**
 * 抽象状态类
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
abstract class State {

    public Activity activity;

    public State(Activity activity) {
        this.activity = activity;
    }

    /**
     * 编辑
     */
    public abstract State edit();

    /**
     * 保存
     */
    public abstract State save();

    /**
     * 提交
     */
    public abstract State submit();

    /**
     * 审核通过
     */
    public abstract State pass();

    /**
     * 审核拒绝
     */
    public abstract State reject();

    /**
     * 开启
     */
    public abstract State start();

    /**
     * 关闭
     */
    public abstract State close();

}

创建活动:

/**
 * 活动
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class Activity {

    /**
     * 活动id
     */
    private String id;

    /**
     * 活动名称
     */
    private String name;

    /**
     * 更新状态
     */
    public State changeState(State state){
        return state;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Activity(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

创建几种状态的具体类:

package com.cloud.bssp.designpatterns.state;

/**
 * 编辑状态
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class EditState extends State {

    public EditState(Activity activity) {
        super(activity);
    }

    @Override
    public State edit() {
        System.out.println("活动正在编辑");
        return this;
    }

    @Override
    public State save() {
        System.out.println("活动已保存");
        return activity.changeState(new SaveState(activity));
    }

    @Override
    public State submit() {
        System.out.println("活动已提交");
        return activity.changeState(new SubmitState(activity));
    }

    @Override
    public State pass() {
        System.out.println("编辑中无法审核");
        return this;
    }

    @Override
    public State reject() {
        System.out.println("编辑中无法审核");
        return this;
    }

    @Override
    public State start() {
        System.out.println("编辑中无法开启");
        return this;
    }

    @Override
    public State close() {
        System.out.println("编辑中无法关闭");
        return this;
    }
}

package com.cloud.bssp.designpatterns.state;

/**
 * 保存状态
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class SaveState extends State{

    public SaveState(Activity activity) {
        super(activity);
    }

    @Override
    public State edit() {
        System.out.println("活动正在编辑中");
        return activity.changeState(new EditState(activity));
    }

    @Override
    public State save() {
        System.out.println("活动已保存");
        return this;
    }

    @Override
    public State submit() {
        System.out.println("活动已提交");
        return activity.changeState(new SubmitState(activity));
    }

    @Override
    public State pass() {
        System.out.println("保存状态无法审核");
        return this;
    }

    @Override
    public State reject() {
        System.out.println("保存状态无法审核");
        return this;
    }

    @Override
    public State start() {
        System.out.println("保存状态无法开启");
        return this;
    }

    @Override
    public State close() {
        System.out.println("保存状态无法关闭");
        return this;
    }
}

package com.cloud.bssp.designpatterns.state;

/**
 * 提交状态
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class SubmitState extends State{

    public SubmitState(Activity activity) {
        super(activity);
    }

    @Override
    public State edit() {
        System.out.println("活动已提交,无法编辑");
        return this;
    }

    @Override
    public State save() {
        System.out.println("活动已提交,无法保存");
        return this;
    }

    @Override
    public State submit() {
        System.out.println("活动已提交,无法再次提交");
        return this;
    }

    @Override
    public State pass() {
        System.out.println("活动已经审核通过");
        return activity.changeState(new PassState(activity));
    }

    @Override
    public State reject() {
        System.out.println("活动已经审核拒绝");
        return activity.changeState(new RejectState(activity));
    }

    @Override
    public State start() {
        System.out.println("未审核无法开启");
        return this;
    }

    @Override
    public State close() {
        System.out.println("未审核无法关闭");
        return this;
    }
}

package com.cloud.bssp.designpatterns.state;

/**
 * 通过状态
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class PassState extends State{

    public PassState(Activity activity) {
        super(activity);
    }

    @Override
    public State edit() {
        System.out.println("审核通过无法编辑");
        return this;
    }

    @Override
    public State save() {
        System.out.println("审核通过无法保存");
        return this;
    }

    @Override
    public State submit() {
        System.out.println("审核通过无法提交");
        return this;
    }

    @Override
    public State pass() {
        System.out.println("审核通过无法再次审核");
        return this;
    }

    @Override
    public State reject() {
        System.out.println("审核通过无法再次审核");
        return this;
    }

    @Override
    public State start() {
        System.out.println("活动已经开启");
        return activity.changeState(new StartState(activity));
    }

    @Override
    public State close() {
        System.out.println("审核通过无法关闭");
        return this;
    }
}

package com.cloud.bssp.designpatterns.state;

/**
 * 拒绝状态
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class RejectState extends State{

    public RejectState(Activity activity) {
        super(activity);
    }

    @Override
    public State edit() {
        System.out.println("审核拒绝无法编辑");
        return this;
    }

    @Override
    public State save() {
        System.out.println("审核拒绝无法保存");
        return this;
    }

    @Override
    public State submit() {
        System.out.println("审核拒绝无法提交");
        return this;
    }

    @Override
    public State pass() {
        System.out.println("审核拒绝无法再次审核");
        return this;
    }

    @Override
    public State reject() {
        System.out.println("审核拒绝无法再次审核");
        return this;
    }

    @Override
    public State start() {
        System.out.println("审核拒绝无法开启");
        return this;
    }

    @Override
    public State close() {
        System.out.println("活动已经关闭");
        return activity.changeState(new StartState(activity));
    }
}

package com.cloud.bssp.designpatterns.state;

/**
 * 开启状态
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class StartState extends State{

    public StartState(Activity activity) {
        super(activity);
    }

    @Override
    public State edit() {
        System.out.println("已开启无法编辑");
        return this;
    }

    @Override
    public State save() {
        System.out.println("已开启无法保存");
        return this;
    }

    @Override
    public State submit() {
        System.out.println("已开启无法提交");
        return this;
    }

    @Override
    public State pass() {
        System.out.println("已开启无法审核");
        return this;
    }

    @Override
    public State reject() {
        System.out.println("已开启无法审核");
        return this;
    }

    @Override
    public State start() {
        System.out.println("已开启无法再次开启");
        return this;
    }

    @Override
    public State close() {
        System.out.println("活动已经关闭");
        return activity.changeState(new CloseState(activity));
    }
}

package com.cloud.bssp.designpatterns.state;

/**
 * 关闭状态
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class CloseState extends State{

    public CloseState(Activity activity) {
        super(activity);
    }

    @Override
    public State edit() {
        System.out.println("活动正在编辑中");
        return activity.changeState(new EditState(activity));
    }

    @Override
    public State save() {
        System.out.println("关闭状态无法保存");
        return this;
    }

    @Override
    public State submit() {
        System.out.println("关闭状态无法提交");
        return this;
    }

    @Override
    public State pass() {
        System.out.println("关闭状态无法再次审核");
        return this;
    }

    @Override
    public State reject() {
        System.out.println("关闭状态无法再次审核");
        return this;
    }

    @Override
    public State start() {
        System.out.println("关闭状态无法开启");
        return this;
    }

    @Override
    public State close() {
        System.out.println("关闭状态无法再次关闭");
        return this;
    }

}

测试类:

package com.cloud.bssp.designpatterns.state;

/**
 * 测试
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class TestDemo {

    public static void main(String[] args) {
        //初始化活动
        Activity activity = new Activity("1", "活动1");
        //初始化编辑状态
        State state = new EditState(activity);
        //保存
        state = state.save();
        //提交
        state = state.submit();
        //审核通过
        state = state.pass();
        //开启
        state = state.start();
        //开启状态下编辑
        state.edit();
        //开启状态下提交
        state.submit();
    }
}

结果:

活动已保存
活动已提交
活动已经审核通过
活动已经开启
已开启无法编辑
已开启无法提交

4、分析

State.png

如上图所示,看到各个关系之间错综复杂,在每种状态里面不同的操作,会返回不同的状态结果,且对于其他状态没有影响。在Activity这个类里面,提供了一个公共的状态改变方法,只需声明局部变量State。

以上方式利于扩展,每个状态各司其职,充分解耦。

缩减上面的状态,以编辑状态为例,总结状态模式的几个主要组成如下图:

State.png

TestDemo:客户端。
State:顶层抽象。
Activity:状态上下文。
EditState:具体当前状态。

5、总结

优点:
1)单一职责原则。 将与特定状态相关的代码放在单独的类中。
2)开闭原则。 无需修改已有状态类和上下文就能引入新状态。
3)通过消除臃肿的状态机条件语句简化上下文代码。
缺点:
如果状态机只有很少的几个状态, 或者很少发生改变, 那么应用该模式可能会显得小题大作。

相关文章

  • 设计模式(二十)状态模式

    1、概述 状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属...

  • 设计模式-状态模式

    设计模式-状态模式 设计模式 状态模式的关键是区分事物内部的状态

  • 设计模式(二十一) 状态模式

    状态模式也是一种行为型模式,当我们的程序中需要一些状态转换,对于不同的状态需要不同的行为时,我们就可以考虑使用状态...

  • 设计模式二十二--状态模式

    定义 当一个状态在内部状态改变时允许改变行为,这个对象看起来像改变了类型。 状态模式的角色 1:抽象状态角色(St...

  • 设计模式(二十一):状态模式

    状态模式(State)又称状态对象模式,主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。状态模式允...

  • 设计模式——状态模式

    设计模式——状态模式 在状态模式中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。 优点: 减少...

  • 设计模式-状态设计模式

    1.定义 对于某个操作,由于其状态的不同,表现出的行为会不同(如遥控器进行音量增加的操作,在电视是开机状态下是可以...

  • 设计模式——状态模式

    前言 设计模式是指导一个程序猿以更好的姿态处理一些问题,而不再像刚学编程的我们,只会使用if-else分支语句,或...

  • 设计模式--状态模式

    基本常识:策略模式与状态模式是双胞胎,在出生时才分开。 假设公司有个糖果机,1当糖果机由糖果,投入25分钱,转动曲...

  • 设计模式——状态模式

    在阎宏博士的《JAVA与模式》一书中开头是这样描述状态(State)模式的:状态模式,又称状态对象模式(Patte...

网友评论

    本文标题:设计模式(二十)状态模式

    本文链接:https://www.haomeiwen.com/subject/uigloktx.html