Enum枚举写的一个简单状态机

Posted 高因咖啡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Enum枚举写的一个简单状态机相关的知识,希望对你有一定的参考价值。

今天下雨,心情有点压抑,所以用枚举写个状态机排解一下心情,顺便记录一下枚举使用方法.

 

package statemachine;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author ZhenWeiLai
 *
 */
public enum StateEnum {

    READY("1", "准备"){
        @Override
        void submit(Entity entity) {
            super.submit(entity);
            //重写更新状态方法,加入自己的业务逻辑
            System.out.println("Ready submit 收尾工作...");
        }
    },
    START("2", "开始"){
        @Override
        void undo(Entity entity) {
            super.undo(entity);
            System.out.println("Start undo 收尾工作...");
        }
    },
    RUN("3", "运行"),
    STOP("4", "停止");

    //状态代码
    private String code;
    //状态名称
    private String name;
    
    //构造方法
    StateEnum(String code, String name){
        this.code = code;
        this.name = name;
        //构造时把代码注册进列表
        StateList.stateList.add(code);
    }

    //更新状态的方法,如果更新状态需要做什么其他操作,那么重写该方法,然后super调用,再加入自己逻辑
    void submit(Entity entity) {
        if (entity.getState() == null && !this.getCode().equals(READY.getCode()))
            throw new RuntimeException("状态不合法");
        else if(entity.getState() == null && this.getCode().equals(READY.getCode())){
            entity.setState(StateList.stateList.get(0));
            return;
        }
            
        if(!StateList.stateList.get((StateList.stateList.indexOf(entity.getState())+1)).equals(this.code))
            throw new RuntimeException("状态不合法");
        
        if(StateList.stateList.contains(this.code)){
            entity.setState(this.code);
        }
    }

    //反操作方法,与提交方法同理
    void undo(Entity entity) {
        //如果当前没有状态,也不是当前枚举状态,那么抛出异常
        if (entity.getState() == null||!entity.getState().equals(this.code))
            throw new RuntimeException("状态不合法");
        //判断是否已经注册进列表的合法状态
            if(StateList.stateList.contains(this.code)){
                Integer codeIndex = StateList.stateList.indexOf(this.code);
                //如果不是初始化状态,那么回退一个状态,否则设置为null
                if(codeIndex>0)
                    entity.setState(StateList.stateList.get(--codeIndex));
                else
                    entity.setState(null);
            }
    }
    
    //根据code获取状态名称
    public static String getNameByCode(String code){
        for(StateEnum item : StateEnum.values()){
            if(item.getCode().equals(code)){
                return item.getName();
            }
        }
         return "";
    }
    
    /**
     * 
     * @author ZhenWeiLai
     * 静态内部类,挺环保的,为了使用这个静态list
     * 因为枚举构造方法不能调用静态属性,原因不明,知道的人请告诉我一声
     */
    static class StateList{
        private static List<String> stateList = new ArrayList<>();
    }
    
    //------------------------------------------------------getter setter-------------------------------------------------------------------------

    
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

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

 

package statemachine;

/**
 * 
 * @author ZhenWeiLai
 * 实体
 */
public class Entity {
    //状态code
    private String state;
    
    /**
     * 获取状态code转译
     * @return
     */
    public String getStateName(){
        return StateEnum.getNameByCode(this.state);
    }
    
    public String getState() {
        return state;
    }
    
    public void setState(String state) {
        this.state = state;
    }
}

 

 

package statemachine;

/**
 * 
 * @author ZhenWeiLai
 *
 */
public class TestClass {
    
    /**
     * 测试方法
     * @param args
     */
    public static void main(String[] args) {
        Entity entity = new Entity();

        StateEnum.READY.submit(entity);
        System.out.println(entity.getStateName());
        StateEnum.START.submit(entity);
        System.out.println(entity.getStateName());
        StateEnum.RUN.submit(entity);
        System.out.println(entity.getStateName());
        StateEnum.STOP.submit(entity);
        System.out.println(entity.getStateName());
        
        StateEnum.STOP.undo(entity);
        System.out.println(entity.getStateName());
        StateEnum.RUN.undo(entity);
        System.out.println(entity.getStateName());
        StateEnum.START.undo(entity);
        System.out.println(entity.getStateName());
        StateEnum.READY.undo(entity);
        System.out.println(entity.getStateName());
    
    }
}

 

控制台输出结果:

Ready submit 收尾工作...
准备
开始
运行
停止
运行
开始
Start undo 收尾工作...
准备

 

以上是关于Enum枚举写的一个简单状态机的主要内容,如果未能解决你的问题,请参考以下文章

使用Java枚举实现简单状态机

使用Java枚举实现简单状态机

使用Java枚举实现简单状态机

使用Java枚举实现简单状态机

使用Java枚举实现简单状态机

Java数据结构之枚举