状态模式(State Pattern)
Posted 顧棟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状态模式(State Pattern)相关的知识,希望对你有一定的参考价值。
状态模式(State Pattern)
状态模式的定义
当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。
状态模式的核心是封装,状态的变更引起了行为的变更,从外部看起来就好像这个对象对应的类发生了改变一样。
状态模式的优点
- 结构清晰,状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足"单一职责原则"。
- 将状态转换显示化,减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
- 状态类职责明确,有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。
- 良好的封装性,这也是状态模式的基本要求,状态变换放置到类的内部来实现,外部的调用不用知道类内部如何实现状态和行为的变换。
状态模式的缺点
- 状态模式的使用必然会增加系统的类与对象的个数。
- 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
- 状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源码。
状态模式的结构
包含以下主要角色。
- 环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
- 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
- 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。
状态模式的实现
通用场景
public abstract class State {
/**
* 定义一个环境角色,提供子类访问
*/
protected Context context;
/**
* 设置环境角色
*/
public void setContext(Context context) {
this.context = context;
}
/**
* 行为1
*/
public abstract void handle1();
/**
* 行为2
*/
public abstract void handle2();
}
public class Context {
/**
* 定义状态
*/
public final static State STATE1 = new ConcreteState1();
public final static State STATE2 = new ConcreteState2();
/**
* 当前状态
*/
private State currentState;
/**
* 获得当前状态
*/
public State getCurrentState() {
return currentState;
}
/**
* 设置当前状态
*/
public void setCurrentState(State currentState) {
this.currentState = currentState;
//切换状态
this.currentState.setContext(this);
}
/**
* 行为委托
*/
public void handle1() {
this.currentState.handle1();
}
public void handle2() {
this.currentState.handle2();
}
}
public class ConcreteState1 extends State {
@Override
public void handle1() {
System.out.println("State1 is doing things");
}
@Override
public void handle2() {
// 设置当前状态为stat2
super.context.setCurrentState(Context.STATE2);
// 过渡到state2状态,由Context实现
super.context.handle2();
}
}
public class ConcreteState2 extends State {
@Override
public void handle1() {
//设置当前状态为state1
super.context.setCurrentState(Context.STATE1);
//过渡到state1状态,由Context实现
super.context.handle1();
}
@Override
public void handle2() {
System.out.println("State2 is doing things");
}
}
public static void main(String[] args) {
//定义环境角色
Context context = new Context();
//初始化状态
context.setCurrentState(new ConcreteState1());
//行为执行
context.handle1();
context.handle2();
}
流程审批场景
public class ActivityInfo {
/**
* 活动ID
*/
private String activityId;
/**
* 活动名称
*/
private String activityName;
/**
* 活动状态
*/
private Enum<Status> status;
/**
* 开始时间
*/
private Date beginTime;
/**
* 结束时间
*/
private Date endTime;
public String getActivityId() {
return activityId;
}
public void setActivityId(String activityId) {
this.activityId = activityId;
}
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
public Enum<Status> getStatus() {
return status;
}
public void setStatus(Enum<Status> status) {
this.status = status;
}
public Date getBeginTime() {
return beginTime;
}
public void setBeginTime(Date beginTime) {
this.beginTime = beginTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
}
public class ActivityService {
private static final Map<String, Enum<Status>> STATUS_MAP = new ConcurrentHashMap<>();
public static void init(String activityId, Enum<Status> status) {
// 模拟查询活动信息
ActivityInfo activityInfo = new ActivityInfo();
activityInfo.setActivityId(activityId);
activityInfo.setActivityName("早起学习打卡领奖活动");
activityInfo.setStatus(status);
activityInfo.setBeginTime(new Date());
activityInfo.setEndTime(new Date());
STATUS_MAP.put(activityId, status);
}
/**
* 查询活动信息
*
* @param activityId 活动ID
* @return 查询结果
*/
public static ActivityInfo queryActivityInfo(String activityId) {
// 模拟查询活动信息
ActivityInfo activityInfo = new ActivityInfo();
activityInfo.setActivityId(activityId);
activityInfo.setActivityName("早起学习打卡领奖活动");
activityInfo.setStatus(STATUS_MAP.get(activityId));
activityInfo.setBeginTime(new Date());
activityInfo.setEndTime(new Date());
return activityInfo;
}
/**
* 查询活动状态
*
* @param activityId 活动ID
* @return 查询结果
*/
public static Enum<Status> queryActivityStatus(String activityId) {
return STATUS_MAP.get(activityId);
}
/**
* 执行状态变更
*
* @param activityId 活动ID
* @param beforeStatus 变更前状态
* @param afterStatus 变更后状态 b
*/
public static synchronized void execStatus(String activityId, Enum<Status> beforeStatus, Enum<Status> afterStatus) {
if (!beforeStatus.equals(STATUS_MAP.get(activityId))) {
return;
}
STATUS_MAP.put(activityId, afterStatus);
}
}
public enum Status {
// 1创建编辑、2待审核、3审核通过(任务扫描成活动中)、4审核拒绝(可以撤审到编辑状态)、5活动中、6活动关闭、7活动开启(任务扫描成活动中)
Editing, Check, Pass, Refuse, Doing, Close, Open
}
public class Result {
public final static String CODE_ERROR = "0001";
public final static String CODE_OK = "0000";
/**
* 编码
*/
private String code;
/**
* 描述
*/
private String info;
public Result(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
/**
* 抽象状态类
*/
public abstract class State {
/**
* 活动提审
*
* @param activityId 活动ID
* @param currentStatus 当前状态
* @return 执行结果
*/
public abstract Result arraignment(String activityId, Enum<Status> currentStatus);
/**
* 审核通过
*
* @param activityId 活动ID
* @param currentStatus 当前状态
* @return 执行结果
*/
public abstract Result checkPass(String activityId, Enum<Status> currentStatus);
/**
* 审核拒绝
*
* @param activityId 活动ID
* @param currentStatus 当前状态
* @return 执行结果
*/
public abstract Result checkRefuse(String activityId, Enum<Status> currentStatus);
/**
* 撤审撤销
*
* @param activityId 活动ID
* @param currentStatus 当前状态
* @return 执行结果
*/
public abstract Result checkRevoke(String activityId, Enum<Status> currentStatus);
/**
* 活动关闭
*
* @param activityId 活动ID
* @param currentStatus 当前状态
* @return 执行结果
*/
public abstract Result close(String activityId, Enum<Status> currentStatus);
/**
* 活动开启
*
* @param activityId 活动ID
* @param currentStatus 当前状态
* @return 执行结果
*/
public abstract Result open(String activityId, Enum<Status> currentStatus);
/**
* 活动执行
*
* @param activityId 活动ID
* @param currentStatus 当前状态
* @return 执行结果
*/
public abstract Result doing(String activityId, Enum<Status> currentStatus);
}
/**
* 活动状态;待审核
*/
public class CheckState extends State {
@Override
public Result arraignment(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "待审核状态不可重复提审");
}
@Override
public Result checkPass(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_OK, "活动审核通过完成");
}
@Override
public Result checkRefuse(String activityId, Enum<Status> currentStatus) {
ActivityService.execStatus(activityId, currentStatus, Status.Refuse);
return new Result(Result.CODE_OK, "活动审核拒绝完成");
}
@Override
public Result checkRevoke(String activityId, Enum<Status> currentStatus) {
ActivityService.execStatus(activityId, currentStatus, Status.Editing);
return new Result(Result.CODE_OK, "活动审核撤销回到编辑中");
}
@Override
public Result close(String activityId, Enum<Status> currentStatus) {
ActivityService.execStatus(activityId, currentStatus, Status.Close);
return new Result(Result.CODE_OK, "活动审核关闭完成");
}
@Override
public Result open(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "非关闭活动不可开启");
}
@Override
public Result doing(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "待审核活动不可执行活动中变更");
}
}
/**
* 活动状态;活动关闭
*/
public class CloseState extends State {
@Override
public Result arraignment(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "活动关闭不可提审");
}
@Override
public Result checkPass(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "活动关闭不可审核通过");
}
@Override
public Result checkRefuse(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "活动关闭不可审核拒绝");
}
@Override
public Result checkRevoke(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "活动关闭不可撤销审核");
}
@Override
public Result close(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "活动关闭不可重复关闭");
}
@Override
public Result open(String activityId, Enum<Status> currentStatus) {
ActivityService.execStatus(activityId, currentStatus, Status.Open);
return new Result(Result.CODE_OK, "活动开启完成");
}
@Override
public Result doing(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "活动关闭不可变更活动中");
}
}
/**
* 活动状态;活动中
*/
public class DoingState extends State {
@Override
public Result arraignment(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "活动中不可提审");
}
@Override
public Result checkPass(String activityId, Enum<Status> currentStatus) {
return new Result(Result.CODE_ERROR, "活动中不可审核通过");
}
@Override
以上是关于状态模式(State Pattern)的主要内容,如果未能解决你的问题,请参考以下文章