状态模式:主要解决某个对象具有不同的状态,根据状态的不同具有不同的行为。状态的变化影响这对象的行为的问题。例如航空订票,机票有不同的状态,根据不同的状态(已登机,未登机,起飞前24小时)决定机票的行为(可退票,可改签等)。又例如银行卡的余额流水决定者用户可存款,可借款,可借款金额。又例如工作流审批过程中,当前申请单的状态决定这下一步是什么行为。像这种 对象的状态影响着对象的行为的情况,并且对象的状态可能随着业务改变而改变,比如会员的级别和会员的优惠之间的关系,会员的级别影响这会员的购物优惠(金额结算行为)。并且随着业务扩大,会员级别很可能会增加,优惠额度也会调整。若使用普通的逻辑判断,每次改变都有修改复杂的逻辑判断。
状态模式的实现:
①:一个环境对象,这个环境对象拥有不同的状态和行为。上面例子中的机票,银行卡、申请单、会员。
②:一个抽象的状态类,
持有环境对象实例,用于在一定条件下修改环境的状态。
定义相关的行为的接口。
③:定义具体的状态类继承了抽象状态类。
下面附上代码:
package stateWorkflow;
//状态的枚举类,把每一种状态都枚举出来
public enum GzdgState {
EDIT("10"),ZSFH("21"),FZZFH("22"),ZZSF("23"),SPJS("30");
private String value;
private GzdgState(String str ){
this.value = str;
}
/**
* @return the value
*/
public String getValue() {
return value;
}
/**
* @param value the value to set
*/
public void setValue(String value) {
this.value = value;
};
}
package stateWorkflow;
/**
* 抽象状态类
* @name:State
* @author: liuds
* @Date: 2017-11-17 下午8:19:52
* @description:
*/
public interface State {
//提交
public void submit(StateManager stateManager);
//退回
public void back(StateManager stateManager);
//获取当前的状态 用户关系的方法审批到哪里了
public GzdgState getState();
}
package stateWorkflow;
/**
* 实现了状态接口 拥有状态的行为
* @name:EditState
* @author: liudsb
* @Date: 2017-11-17 下午8:52:10
* @description:
*/
public class EditState implements State {
@Override
public void submit(StateManager stateManager) {
System.out.println("提交给主审");
stateManager.setState(new ZsfhState());
}
@Override
public void back(StateManager stateManager) {
// 这里退回不设置状态 保持现有状态
System.out.println("已经在组员");
}
@Override
public GzdgState getState() {
return (GzdgState.EDIT);
}
}
package stateWorkflow;
/**
*
* @name:ZsfhState
* @author: liudsb
* @Date: 2017-11-17 下午8:53:37
* @description:
*/
public class ZsfhState implements State {
@Override
public void submit(StateManager stateManager) {
System.out.println("提交副组长");
stateManager.setState(new FzzfhState());
}
@Override
public void back(StateManager stateManager) {
System.out.println("退回组员");
stateManager.setState(new EditState());
}
@Override
public GzdgState getState() {
return GzdgState.ZSFH;
}
}
package stateWorkflow;
/**
* 实现了状态接口 拥有状态的行为
* @name:FzzfhState
* @author: liudsb
* @Date: 2017-11-17 下午8:52:10
* @description:
*/
public class FzzfhState implements State {
@Override
public void submit(StateManager stateManager) {
System.out.println("提交给组长");
stateManager.setState(new ZzfhState());
}
@Override
public void back(StateManager stateManager) {
System.out.println("退回给主审");
stateManager.setState(new ZsfhState());
}
@Override
public GzdgState getState() {
return GzdgState.FZZFH;
}
}
package stateWorkflow;
/**
*
* @name:ZzfhState
* @author: liudsb
* @Date: 2017-11-17 下午8:53:47
* @description:
*/
public class ZzfhState implements State {
@Override
public void submit(StateManager stateManager) {
System.out.println("审批结束");
stateManager.setState(new SpjsState());
}
@Override
public void back(StateManager stateManager) {
System.out.println("退回副组长结束");
stateManager.setState(new FzzfhState());
}
@Override
public GzdgState getState() {
return GzdgState.SPJS;
}
}
package stateWorkflow;
/**
* 实现了状态接口 拥有状态的行为
* @name:SpjsState
* @author: liudsb
* @Date: 2017-11-17 下午8:52:10
* @description:
*/
public class SpjsState implements State {
@Override
public void submit(StateManager stateManager) {
System.out.println("审批结束");
// TODO Auto-generated method stub
}
@Override
public void back(StateManager stateManager) {
System.out.println("审批结束");
// TODO Auto-generated method stub
}
@Override
public GzdgState getState() {
return GzdgState.SPJS;
}
}
以下是环境类,该类拥有状态的实例,代表目前环境是何种状态。并且拥有当前用户关系的行为,提交退回操作。
package stateWorkflow;
public class StateManager {
//记录当前状态
private State state ;
public StateManager( State state){
this.state = state;
}
/**
* 设置当前状态
*/
public void setState(State state) {
this.state = state;
}
/**
* 获取当前状态
*/
public State getState() {
return state;
}
//管理类只知道提交,具体提交给谁 ,由当前的状态来决定。
public void submit(){
state.submit(this);
}
//管理类退回,具体退回给谁 ,由当前的状态来决定。
public void back(){
state.back(this);
}
}
测试代码
package stateWorkflow;
public class StateTest {
public static void main(String [] args){
//初始化状态为编制状态
StateManager stateManager = new StateManager(new EditState());
stateManager.submit();//提交给主审
stateManager.submit();//提交副组长
stateManager.submit();//提交组长
//stateManager.submit(); //如果 这句执行那么就
//stateManager.submit();
//stateManager.submit();
stateManager.back();//退回副组长
stateManager.back();//退回主审
stateManager.back();//退回组员
stateManager.back();//继续退回状态不变
stateManager.back();//继续退回状态不变
}
}
测试结果
从结果中看出,退回之后,继续退回则不会执行,仍然保证当前的状态。
状态机模式解决了固定审批过程中审批流程复杂引起的逻辑复杂问题,使用包含行为的状态类,把不同的行为分离,使用管理类对状态类进行管理。另外有责任链模式也用来解决工作流的问题,只不过责任链模式是解决审批过程中,审批流程动态变化的问题,而不是单纯的行为随状态变化。