用状态模式实现状态机工作流

概述

状态机工作流由一组状态组成。一个状态被指示为初始状态。每个状态都可以接收一组特定事件。视事件而定,可以转换到另一个状态。状态机工作流可以有最终状态。当转换到最终状态时,工作流将完成。

场景

针对我上篇博客设计的一个简单的状态机工作流,流程图如下:

用状态模式实现状态机工作流_第1张图片

我们来设计个用设计模式中的状态模式来设计这个工作流。

设计

先看看它的User Case功能设计:

用状态模式实现状态机工作流_第2张图片

再看看它的Class diagram设计:

用状态模式实现状态机工作流_第3张图片

 

实现

先创建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");
        }
    }
}

 

查看运行的结果:

用状态模式实现状态机工作流_第4张图片

欢迎各位参与讨论,如果觉得对你有帮助,请点击image    推荐下,万分谢谢.

作者:spring yang

出处:http://www.cnblogs.com/springyangwc/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

你可能感兴趣的:(状态模式)