状态模式实战运用

目录

前言

UML

plantuml

类图

实战代码

Form

State

Client


前言

通常一个完整的业务流程中,会经历多个阶段,每个阶段即一个业务状态,不同状态下对应这不同的业务处理逻辑。

无脑堆砌 if else 做判断然后选择对应的业务处理其实也能够完成该需求,只不过这样写代码不够优雅。使用状态模式来处理这种业务场景,能让程序可读性更好,易于维护和扩展。

状态模式和策略模式从 UML 上看其实是一样的,很容易混淆。

两者的区别就是策略模式下的策略是由客户端自主选择的,且每个策略之间并没有任何关系;而状态模式下的状态之间是可以互相转换的,每个状态下的行为除了必要的业务处理外,还会涉及到状态转化。

UML

plantuml

@startuml
'https://plantuml.com/class-diagram

interface State {
    + next(Context) : void
    + prev(Context) : void
}

class StateA {
    + next(Context) : void
    + prev(Context) : void
}

class StateB {
    + next(Context) : void
    + prev(Context) : void
}

class Context {
    - state : State
    + Context(State)
    + next() : void
    + prev() : void
}

State <|.. StateA
State <|.. StateB

Context "1" --> "1" State

@enduml

类图

实战代码

业务流程存在三个状态 INIT,PROCESSING,COMPLETE

每个状态可以通过下一步,上一步来进行状态转化

使用枚举类来实现状态模式如下所示

Form

public class Form {
    int state;

    Form() {
        state = 1;
    }

    public int getState() {
        return state;
    }

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

State

public enum State {
    INIT(1, "初始化") {
        public void nextStep(Form form) {
            //其他业务操作
            form.setState(PROCESSING.getValue());
        }

        public void preStep(Form form) {
            throw new RuntimeException("已经是最初状态,无法上一步");
        }
    },
    PROCESSING(2, "处理中") {
        public void nextStep(Form form) {
            //其他业务操作
            form.setState(COMPLETE.getValue());
        }

        public void preStep(Form form) {
            //其他业务操作
            form.setState(INIT.getValue());
        }
    },
    COMPLETE(3, "完成") {
        public void nextStep(Form form) {
            throw new RuntimeException("已经是最终状态,无法下一步");
        }

        public void preStep(Form form) {
            //其他业务操作
            form.setState(COMPLETE.getValue());
        }
    };

    private final Integer value;
    private final String desc;
    private static final Map<Integer, State> map = Arrays.stream(values())
            .collect(toMap(State::getValue, e -> e));

    private State(Integer value, String desc) {
        this.value = value;
        this.desc = desc;
    }

    public Integer getValue() {
        return this.value;
    }

    public String getDesc() {
        return this.desc;
    }

    public void nextStep(Form form) {}

    public void preStep(Form form) {}

    public static State getEnum(Integer value) {
        return map.get(value);
    }
}

Client

public class Client {

    public static void main(String[] args) {
        Form form = new Form();

        State state = State.getEnum(form.getState());
        state.nextStep(form);
        System.out.println(form.getState());

        state = State.getEnum(form.getState());
        state.nextStep(form);
        System.out.println(form.getState());

        state.preStep(form);
        System.out.println(form.getState());
    }
}

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值