本文以项目中的一个工作流模块,演示责任链模式、策略模式、命令模式的组合实现!
流程简介
最近在做的一个项目,涉及到的是一个流程性质的需求。关于工程机械行业的服务流程:服务任务流程和备件发运流程。
项目之初,需求不是很清晰,算是演化模型吧。先出一个简单版本,然后根据用户的使用情况,再进一步探测新需求。所以也就是说这两个流程中的每一步暂时都不是固定的,而应该是可配置、可增减的。
目前暂定的两个流程示意图如下:
以上为两个流程的大致过程,当然实际过程中,可能还要走其他的流程。
但是,仔细分析,你会看到。不管有多少个中间步骤,它们始终都对应着它们在该流程中所处的状态:
///
/// 服务流程状态枚举
///
public enum MaintanStateEnum
{
non_assign, //已创建,待分配
non_accept, //已分配,待接收
maintaining, //已接收,服务中
non_confirm, //完成服务,待确认
non_userConfirm, //已确认,待客户确认
non_feedback, //客户已确认,待回访
feedbacked, //回访完成,流程结束
goback //退回分配,此为动作,为了方便编码,不对应服务状态
}
你会看到non_后面跟的都是一个个动作。在这里分清状态和动作是很重要的,不然就很难理清了。还有有时一个动作对应着前后状态,不要出现重复的状态比如:created(创建完成)和non_assign(待分配)在这里就是所谓的重复状态。
这些状态其实就是贯穿着整个流程的主线,类似于一个城市的主干道一样。我们只要抓着这样一天线索来思考,就能够化繁为简。
每个步骤可配置,各个步骤不相耦合,实现调用端一致性——责任链模式
而责任链模式,正是为此而生的!
在这里,我采用了责任链模式来封装这种步骤的不确定带来的变化。
首先我们有必要先了解一下,什么是责任链模式:
职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
适用场景:
1、有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定;
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
3、处理一个请求的对象集合应被动态指定。
可以看到无论是上面哪种场景,都存在一个多对一的关系。在这个流程中,一很明显对应着服务流程(说白了就是数据库服务任务的一条记录)。大部分情况下,我们都在完成对一条服务中相关字段的修改,同时置不同的服务状态。而多,在这里应该对应着不同的步骤。
下面来看看实现:
///
/// 维修服务 处理器-抽象基类
///
public abstract class ServiceHandler
{
protected ServiceHandler nextHandler;
public virtual void Handle(MaintenanceForm maintenanceForm, object otherParams)
{
if (nextHandler!=null)
{
nextHandler.Handle(maintenanceForm, otherParams);
}
}
}
这是一个抽象处理器,流程中每个步骤的处理器,会覆写这个处理器的处理方法:
创建:
///
/// 创建服务单流程--应对接线员/服务接收员角色【或者其他具有创建权限的其他角色】
///
public class CreateHanlder:ServiceHandler
{
public override void Handle(MaintenanceForm maintenanceForm, object otherParams)
{
//如果已创建(未分配)
if (maintenanceForm.CurrentState==MaintanStateEnum.non_assign)
{
//创建该服务单
return;
}
else //已分配,则传递给下一个流程(假定为分配流程)
{
base.Handle(maintenanceForm,otherParams);<