用状态模式实现状态机工作流
概述
状态机工作流由一组状态组成。一个状态被指示为初始状态。每个状态都可以接收一组特定事件。视事件而定,可以转换到另一个状态。状态机工作流可以有最终状态。当转换到最终状态时,工作流将完成。
场景
针对我上篇博客设计的一个简单的状态机工作流,流程图如下:
我们来设计个用设计模式中的状态模式来设计这个工作流。
设计
先看看它的User Case功能设计:
再看看它的Class diagram设计:
实现
先创建Enums class:
/******************************************************************************** ** Class Name: Enums ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: Enums class *********************************************************************************/ using System; namespace WorkFlowCommon { public enum ApplicationState { None, Draft, InProgress, Complete, } public enum WorkFlowState { None, Common, Manager, Done, Refuse } [Flags] public enum ActivityState { Create=1, Edit=2, Resbmit=4, Submit=8, Revoke=16, Approve=32, Reject=64, Read=128, None=256 } }
再创建IActivity Interface:
/******************************************************************************** ** Class Name: IActivity ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: IActivity interface *********************************************************************************/ namespace WorkFlowService.IDAL { using WorkFlowCommon; public interface IActivity { WorkFlowState Execute(ActivityState activityState); } }
再创建IActivityState interface
/******************************************************************************** ** Class Name: IActivityState ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: IActivityState interface *********************************************************************************/ namespace WorkFlowService.IDAL { using WorkFlowCommon; public interface IActivityState { ActivityState GetActivityState(); } }
再创建IStateBase interface
/******************************************************************************** ** Class Name: IStateBase ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: IStateBase interface *********************************************************************************/ namespace WorkFlowService.IDAL { using WorkFlowCommon; public interface IStateBase : IActivity, IActivityState { WorkFlowState GetCurrentState(); } }
再创建CommonState class
/******************************************************************************** ** Class Name: CommonState ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: CommonState class *********************************************************************************/ namespace WorkFlowService.DAL { using WorkFlowCommon; using IDAL; public class CommonState : IStateBase { public WorkFlowState Execute(ActivityState activityState) { if (activityState == ActivityState.Submit || activityState == ActivityState.Resbmit) return WorkFlowState.Manager; return WorkFlowState.Common; } public WorkFlowState GetCurrentState() { return WorkFlowState.Common; } public ActivityState GetActivityState() { return ActivityState.Submit | ActivityState.Read | ActivityState.Revoke | ActivityState.Resbmit; } } }
再创建DoneState Class
/******************************************************************************** ** Class Name: DoneState ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: DoneState class *********************************************************************************/ namespace WorkFlowService.DAL { using WorkFlowCommon; using IDAL; public class DoneState : IStateBase { public WorkFlowState Execute(ActivityState activityState) { return WorkFlowState.Done; } public WorkFlowState GetCurrentState() { return WorkFlowState.Done; } public ActivityState GetActivityState() { return ActivityState.Read; } } }
再创建ManageState class
/******************************************************************************** ** Class Name: ManageState ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: ManageState class *********************************************************************************/ namespace WorkFlowService.DAL { using WorkFlowCommon; using IDAL; public class ManageState : IStateBase { public WorkFlowState Execute(ActivityState activityState) { if (activityState == ActivityState.Approve) return WorkFlowState.Done; if (activityState == ActivityState.Revoke) return WorkFlowState.Common; return WorkFlowState.Refuse; } public WorkFlowState GetCurrentState() { return WorkFlowState.Manager; } public ActivityState GetActivityState() { return ActivityState.Approve | ActivityState.Reject | ActivityState.Read; } } }
再创建RefuseState class
/******************************************************************************** ** Class Name: RefuseState ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: RefuseState class *********************************************************************************/ namespace WorkFlowService.DAL { using WorkFlowCommon; using IDAL; public class RefuseState : IStateBase { public WorkFlowState Execute(ActivityState activityState) { return WorkFlowState.Refuse; } public WorkFlowState GetCurrentState() { return WorkFlowState.Refuse; } public ActivityState GetActivityState() { return ActivityState.Read; } } }
再创建StateMapping class:
/******************************************************************************** ** Class Name: StateMapping ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: StateMapping class *********************************************************************************/ namespace WorkFlowService.Help { using System.Collections.Generic; using DAL; using IDAL; public class StateMapping { public List<IStateBase> StateBasesList; private StateMapping() { Init(); } private static StateMapping _instance; public static StateMapping Instance { get { if (_instance == null) _instance = new StateMapping(); return _instance; } } private void Init() { StateBasesList = new List<IStateBase> { new CommonState(), new ManageState(), new DoneState(), new RefuseState() }; } } }
再创建WorkFlowEngine class
/******************************************************************************** ** Class Name: WorkFlowEngine ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: WorkFlowEngine class *********************************************************************************/ namespace WorkFlowService.BLL { using WorkFlowCommon; using DAL; using Help; using IDAL; public class WorkFlowEngine { private IStateBase GetCurrentWorkFlowStateByWorkFlowState(WorkFlowState workFlowState) { foreach (var iStateBase in StateMapping.Instance.StateBasesList) { if (iStateBase.GetCurrentState() == workFlowState) return iStateBase; } return new CommonState(); } public WorkFlowState Execute(WorkFlowState workFlowState,ActivityState activityState) { return GetCurrentWorkFlowStateByWorkFlowState(workFlowState).Execute(activityState); } public ActivityState GetActivityStateByWorkFlowState(WorkFlowState workFlowState) { return GetCurrentWorkFlowStateByWorkFlowState(workFlowState).GetActivityState(); } } }
最后创建Nunit Test
/******************************************************************************** ** Class Name: TestStateWorkFlowTest ** Author: spring yang ** Create date: 2013-3-13 ** Modify: spring yang ** Modify Date: 2012-3-13 ** Summary: TestStateWorkFlowTest interface *********************************************************************************/ namespace TestCommunication.WorkflowService { using Common; using NUnit.Framework; using WFService; public class TestStateWorkFlowTest : BaseActivity { private WorkFlowServiceClient WfServiceInstance { get { return new WorkFlowServiceClient(); } } [Test] public void TestNewWorkflow() { var appEntity = new AppInfoModel { ActivityState = ActivityState.Submit.ToString(), AppId = "001", WorkflowName = "TestStateWorkFlow", UserId = "001", CurrentState = "Common" }; var result = WfServiceInstance.NewWorkFlow(appEntity); Assert.AreEqual(result, "Manage"); } [Test] public void TestManageApproveWorkflow() { var appEntity = new AppInfoModel { ActivityState = ActivityState.Submit.ToString(), AppId = "002", WorkflowName = "TestStateWorkFlow", UserId = "002", CurrentState = "Common" }; var result = WfServiceInstance.NewWorkFlow(appEntity); Assert.AreEqual(result, "Manage"); var manageEntity = new AppInfoModel { ActivityState = ActivityState.Approve.ToString(), AppId = "002", WorkflowName = "TestStateWorkFlow", UserId = "003", CurrentState = "Manage" }; var manageResult = WfServiceInstance.Execute(manageEntity); Assert.AreEqual(manageResult, "Done"); } [Test] public void TestManageRejectWorkFlow() { var appEntity = new AppInfoModel { ActivityState = ActivityState.Submit.ToString(), AppId = "004", WorkflowName = "TestStateWorkFlow", UserId = "004", CurrentState = "Common" }; var result = WfServiceInstance.NewWorkFlow(appEntity); Assert.AreEqual(result, "Manage"); var manageEntity = new AppInfoModel { ActivityState = ActivityState.Reject.ToString(), AppId = "004", WorkflowName = "TestStateWorkFlow", UserId = "005", CurrentState = "Manage" }; var manageResult = WfServiceInstance.Execute(manageEntity); Assert.AreEqual(manageResult, "Refuse"); } [Test] public void TestSaveWorkflow() { var appEntity = new AppInfoModel { ActivityState = ActivityState.Save.ToString(), AppId = "006", WorkflowName = "TestStateWorkFlow", UserId = "006", CurrentState = "Common" }; var result = WfServiceInstance.NewWorkFlow(appEntity); Assert.AreEqual(result, "Common"); } [Test] public void TestRevokeWorkflow() { var appEntity = new AppInfoModel { ActivityState = ActivityState.Submit.ToString(), AppId = "007", WorkflowName = "TestStateWorkFlow", UserId = "007", CurrentState = "Common" }; var result = WfServiceInstance.NewWorkFlow(appEntity); Assert.AreEqual(result, "Manage"); var commonEntity = new AppInfoModel { ActivityState = ActivityState.Revoke.ToString(), AppId = "007", WorkflowName = "TestStateWorkFlow", UserId = "007", CurrentState = "Common" }; var revokeResult = WfServiceInstance.Execute(commonEntity); Assert.AreEqual(revokeResult, "Common"); } [Test] public void TestResubmitWorkflow() { var appEntity = new AppInfoModel { ActivityState = ActivityState.Submit.ToString(), AppId = "007", WorkflowName = "TestStateWorkFlow", UserId = "007", CurrentState = "Common" }; var result = WfServiceInstance.NewWorkFlow(appEntity); Assert.AreEqual(result, "Manage"); var commonEntity = new AppInfoModel { ActivityState = ActivityState.Revoke.ToString(), AppId = "007", WorkflowName = "TestStateWorkFlow", UserId = "007", CurrentState = "Common" }; var revokeResult = WfServiceInstance.Execute(commonEntity); Assert.AreEqual(revokeResult, "Common"); var resubmitEntity = new AppInfoModel { ActivityState = ActivityState.Resubmit.ToString(), AppId = "007", WorkflowName = "TestStateWorkFlow", UserId = "007", CurrentState = "Common" }; var lastResult = WfServiceInstance.Execute(resubmitEntity); Assert.AreEqual(lastResult, "Manage"); } } }
查看运行的结果:
欢迎各位参与讨论,如果觉得对你有帮助,请点击 推荐下,万分谢谢.
作者:spring yang
出处:http://www.cnblogs.com/springyangwc/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。