设计模式之状态模式(State Design Pattern)

状态模式,是11种行为型模式之一。一个生存在流程整个周期的对象,因事件触发改变对象的状态进而影响对象的行为(流程的走向)。状态模式就是把对象的行为与状态进行封装,通过改变状态进而影响行为。

状态模式几个关键对象类型:

Context: 一个生存在流程整个周期的对象

State: 封装对象状态的抽象类(State)和具体实现类

本文以请假流程为例,如图:

 

首先找出所有状态

  • 0-草稿
  • 1-申请
  • 2-主管同意
  • 3-主管不同意
  • 4-部门同意
  • 5-部门不同意
  • 6-人事备案

其次找出事件

  • 0-创建草稿
  • 1-提交申请
  • 2-提交主管审批
  • 3-提交部门审批
  • 4-提交人事备案

先看看未使用状态模式实现:

//流程申请表单
class Form {
   private int days; // 请假天数
   private String type; //请假类型
   private String reason; //原因

   Form(int days,String type,String reason){
     this.days = days;
     this.type = type;
     this.reason = reason;
   }

   //省略geter、seter方法
}

class Context {

     private Form form;
     int state = 1; 

     Context(Form form, State state) {
        this.form = form;
        this.state = state;
     }
     
     //省略geter、seter方法
     
}

//流程引擎
class WorkFlowEngine {

    Context context;

    WorkFlowEngine () {
      this.context = new Context();
    }

    public void create(Form form) {
      this.context.setForm(form);
      this.context.setState(0);
    }
    
    public void submit() {
      if (this.context.getState() == 0) {
        this.context.setState(1)
      } 
      if (this.context.getState() == 4) {
        this.context.setState(6)
      }
    }

    public void submit(int event) {
      if (this.context.getState() == 1) {
        if (event == 0)
          this.context.setState(3)
        else 
          this.context.setState(2)
      } else if (this.context.getState() == 2) {
        if (event == 0)
          this.context.setState(5)
        else 
          this.context.setState(4)
      } else if (this.context.getState() == 3) {
        if (event == 1)
          this.context.setState(2)
      } else if (this.context.getState() == 5) {
        if (event == 0)
          this.context.setState(3)
        else 
          this.context.setState(2)
      }
    }

}

public class Client {
    public static void main(String[] args) {
        Form form = new Form(3,"病假","发烧了")
        WorkFlowEngine engine = new WorkFlowEngine();
        //0-创建草稿
        engine.create(form);
        //1-提交申请
        engine.submit();
        //2-提交主管审批
        engine.submit(1);
        //3-提交部门审批
        engine.submit(1);
        //4-提交人事备案
        engine.submit();
    }
}

 WorkFlowEngine 有很多的if分支,当流程有变化时,需要修改WorkFlowEngine,不符合开闭原则。

状态模式实现:

//流程申请表单
class Form {
   private int days; // 请假天数
   private String type; //请假类型
   private String reason; //原因

   Form(int days,String type,String reason){
     this.days = days;
     this.type = type;
     this.reason = reason;
   }

   //省略geter、seter方法
}

//定义状态抽象
interface State {
   public void action(Context context);
   public void action(Context context, int event);
}

//状态实现类
//草稿
class State0 implements State {
    
   int state = 0; 
 
   public void action(Context context) {
     context.setState(new State1());
   }
   public void action(Context context, int event) {

   }
   //省略geter、seter方法

}
//申请
class State1 implements State {
   int state = 1; 
 
   public void action(Context context) {
   }

   public void action(Context context, int event) {
     if (event = 0) //不同意
        context.setState(new State3());
      else
        context.setState(new State2());
   }
   //省略geter、seter方法

}
//主管同意
class State2 implements State {
   int state = 2; 

   public void action(Context context) {
   }
   public void action(Context context, int event) {
     if (event = 0) //不同意
        context.setState(new State5());
      else
        context.setState(new State4());
   }
   //省略geter、seter方法
}

//省略其他状态代码



class Context {

     private Form form;
     private State state; //状态改为状态对象

     Context(Form form, State state) {
        this.form = form;
        this.state = state;
     }
     
     //省略geter、seter方法
     
}

//流程引擎
class WorkFlowEngine {

    Context context;

    WorkFlowEngine () {
      this.context = new Context();
    }

    public void create(Form form) {
      this.context.setForm(form);
      this.context.setState(new State0());
    }

    public void submit() {
      this.context.getState().action(this.context);
    }

    public void submit(int event) {
      this.context.getState().action(this.context, event);
    }

}


public class Client {
    public static void main(String[] args) {
        Form form = new Form(3,"病假","发烧了")
        WorkFlowEngine engine = new WorkFlowEngine();
        //0-创建草稿
        engine.create(form);
        //1-提交申请
        engine.submit();
        //2-提交主管审批
        engine.submit(1);
        //3-提交部门审批
        engine.submit(1);
        //4-提交人事备案
        engine.submit();
    }
}

 使用状态模式之后,WorkFlowEngine与流程状态进行了解耦,流程的变化不再影响WorkFlowEngine,更符合开闭原则。WorkFlowEngine、State类职责更加单一也更符合单一职责原则。

职责链模式遵循的设计原则和思想:

  • 单一职责原则:把状态有关的动作封装到单独的状态类中,解耦WorkFlowEngine与流程,让WorkFlowEngine与State职责单一;
  • 开闭原则:添加状态,只需要添加一个状态类,修改与状态有关的状态,不需要修改WorkFlowEngine及Context;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值