状态机、状态模式

一、状态模式

一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类
image.png

状态类

public enum State {
    RAIN,
    SUNNY,
    THURSDAY
}

worker.java

package com.vv.status;

public class Worker {

    private String name;

    private State state;


    public static void main(String[] args) {
        Worker worker = new Worker();
        worker.setName("兵子");
        worker.setState(State.SUNNY);
        worker.oneDay();
    }
    
    public void oneDay(){
        System.out.println("7:00 上班");
        if (state == State.RAIN){
            System.out.println("今天下雨,坐公交车上班");
        }else if (state == State.SUNNY){
            System.out.println("晴天,骑车上班");
        }else if (state == State.THURSDAY){
            System.out.println("今天星期四,吃肯德基");
        }
        System.out.println("23:00 下班");
    }
    
    public String getName() {
        return name;
    }

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

    public State getState() {
        return state;
    }

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

通过if else实现

public interface IState {
    void handle();
}
public class RainState implements IState {
    @Override
    public void handle() {
        System.out.println("今天下雨,坐公交车上班");
    }
}
public class Worker {

    private String name;

    private IState iState;


    public static void main(String[] args) {
        Worker worker = new Worker();
        worker.setName("兵子");
        worker.setiState(new RainState());
        worker.oneDay4MachineModel();
    }


    public void oneDay4MachineModel(){
        System.out.println("7:00 上班");
        iState.handle();
        System.out.println("23:00 下班");
    }


    public String getName() {
        return name;
    }

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

    public IState getiState() {
        return iState;
    }

    public void setiState(IState iState) {
        this.iState = iState;
    }
}

实际就是多态思想,取代之前的if else
状态模式和策略者模式实际上是比较相近的,策略模式功能更强大

二、状态和策略者

策略模式:其思想是针对一组算法,将每一种算法都封装到具有共同接口的独立的类中,从而是他们可以相互替换。策略模式最大的特点是使得算法可以在不影响客户端的情况下发生变化,从而改变不同的功能

状态模式:允许一个对象在其内部状态改变时改变他的行为,对象看起来似乎修改了它的类

三、状态机

image.png
由现态转化为次态的过程中,需要经历某个事件并执行对应的动作,比如说现态是下单,经历了支付这个事件,动作为处理支付逻辑,转账汇款,最终转化为次态为已下单

四、请假流程

image.png

public enum State {

    FINSH,
    UN_SUBMIT,
    LEADER_CHECK,
    HR_CHECK;

}
public class Test {


    static State getNext(State state){
        if (state == State.UN_SUBMIT){
            return State.LEADER_CHECK;
        }else if (state == State.LEADER_CHECK){
            return State.HR_CHECK;
        }else if (state == State.HR_CHECK){
            return State.FINSH;
        }
        throw new IllegalArgumentException("非法状态");
    }

    public static void main(String[] args) {
        State state = State.UN_SUBMIT;
        System.out.println(getNext(state));
    }
}

if else方式实现状态切换

public enum State {

    FINSH{
        @Override
        State getNext() {
            return this;
        }
    },
    UN_SUBMIT{
        @Override
        State getNext() {
            return LEADER_CHECK;
        }
    },
    LEADER_CHECK{
        @Override
        State getNext() {
            return HR_CHECK;
        }
    },
    HR_CHECK{
        @Override
        State getNext() {
            return FINSH;
        }
    };

    abstract State getNext();
}
public class Test {
    public static void main(String[] args) {
        State state = State.UN_SUBMIT;
        System.out.println(state.getNext());
    }
}

在枚举中定义一个抽象方法,通过枚举实现一个有限状态机,替代if else 写法
缺陷:在领导审批过程中,领导可能同意也可能拒绝,可能并不会直接到Hr审批,所以不仅需要当前状态,还需要一个事件

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>23.1-jre</version>
</dependency>

引入状态和事件两个元素确定下一个状态可以用两个map嵌套的方式实现

public class StateMachine {

    private static HashBasedTable<State,Event,State> hashBasedTable = HashBasedTable.create();

    static {
        hashBasedTable.put(State.UN_SUBMIT,Event.SUBMIT,State.LEADER_CHECK);
        hashBasedTable.put(State.LEADER_CHECK,Event.PASS,State.HR_CHECK);
        hashBasedTable.put(State.HR_CHECK,Event.PASS,State.FINISH);
        hashBasedTable.put(State.LEADER_CHECK,Event.REJECT,State.REJECT);
        hashBasedTable.put(State.HR_CHECK,Event.REJECT,State.REJECT);
    }

    public static State getNext(State state, Event event){
        State result = hashBasedTable.get(state, event);
        if (result == null){
            throw new IllegalArgumentException("未找到对应状态");
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(getNext(State.HR_CHECK, Event.REJECT));
    }

}

引入经历事件后执行的逻辑:

public enum Event {
    SUBMIT,
    PASS,
    REJECT;
}
public enum State {
    REJECT,
    FINISH,
    UN_SUBMIT,
    LEADER_CHECK,
    HR_CHECK;
}
public interface IStateHandle<T,R> {
    R handle(T t);
}
public class LeaderPassHandle implements IStateHandle<String,String> {
    @Override
    public String handle(String s) {
        System.out.println(String.format("收到了%s",s));
        return "领导审核完了";
    }
}
public class SopProcess {
    private State from;
    private State to;
    private Event event;
    private IStateHandle stateHandle;

    public State getFrom() {
        return from;
    }

    public void setFrom(State from) {
        this.from = from;
    }

    public State getTo() {
        return to;
    }

    public void setTo(State to) {
        this.to = to;
    }

    public Event getEvent() {
        return event;
    }

    public void setEvent(Event event) {
        this.event = event;
    }

    public IStateHandle getStateHandle() {
        return stateHandle;
    }

    public void setStateHandle(IStateHandle stateHandle) {
        this.stateHandle = stateHandle;
    }
}
public class SopProcessBuilder {
    private SopProcess sopProcess;

    public void setSopProcess(SopProcess sopProcess){
        this.sopProcess = sopProcess;
    }

    public static SopProcessBuilder getInstance(){
        SopProcessBuilder sopBuilder = new SopProcessBuilder();
        sopBuilder.setSopProcess(new SopProcess());
        return sopBuilder;
    }

    public SopProcessBuilder from(State state){
        sopProcess.setFrom(state);
        return this;
    }

    public SopProcessBuilder to(State state){
        sopProcess.setTo(state);
        return this;
    }

    public SopProcessBuilder event(Event event){
        sopProcess.setEvent(event);
        return this;
    }

    public SopProcess build(){
        return sopProcess;
    }
}
abstract class AbstructStateMachine {

    static class SopExec{
        private State nextState;
        private IStateHandle stateHandle;

        public State getNextState() {
            return nextState;
        }

        public void setNextState(State nextState) {
            this.nextState = nextState;
        }

        public IStateHandle getStateHandle() {
            return stateHandle;
        }

        public void setStateHandle(IStateHandle stateHandle) {
            this.stateHandle = stateHandle;
        }
    }

    private static HashBasedTable<State,Event,SopExec> hashBasedTable = HashBasedTable.create();

    {
        List<SopProcess> sopProcesses = init();
        sopProcesses.forEach(item ->{
            SopExec sopExec = new SopExec();
            sopExec.setNextState(item.getTo());
            sopExec.setStateHandle(item.getStateHandle());
            hashBasedTable.put(item.getFrom(),item.getEvent(),sopExec);
        });
    }

    abstract List<SopProcess> init();

    public State getNext(State state,Event event){
        SopExec result = hashBasedTable.get(state, event);
        if (result == null){
            throw new IllegalArgumentException("未找到状态");
        }
        return result.getNextState();

    }

    public IStateHandle getHandle(State state,Event event){
        SopExec result = hashBasedTable.get(state, event);
        if (result == null){
            throw new IllegalArgumentException("未找到状态");
        }
        return result.getStateHandle();
    }

}
public class NewStateMachine extends AbstructStateMachine {
    @Override
    List<SopProcess> init() {
        return Arrays.asList(
                SopProcessBuilder.getInstance()
                        .from(State.UN_SUBMIT)
                        .event(Event.SUBMIT)
                        .to(State.LEADER_CHECK)
                        .build(),
                SopProcessBuilder.getInstance()
                        .from(State.UN_SUBMIT)
                        .event(Event.SUBMIT)
                        .to(State.LEADER_CHECK)
                        .build());
    }
}

    public static void main(String[] args) {
        NewStateMachine newStateMachine = new NewStateMachine();
        State state = newStateMachine.getNext(State.LEADER_CHECK, Event.PASS);
        System.out.println(state);
        IStateHandle<String,String> stateHandle = newStateMachine.getHandle(State.LEADER_CHECK, Event.PASS);
        String result = stateHandle.handle("123");
        System.out.println(result);
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值