用狀態模式實現狀態機工作流


概述

狀態機工作流由一組狀態組成。一個狀態被指示為初始狀態。每個狀態都可以接收一組特定事件。視事件而定,可以轉換到另一個狀態。狀態機工作流可以有最終狀態。當轉換到最終狀態時,工作流將完成。

場景

針對我上篇博客設計的一個簡單的狀態機工作流,流程圖如下:

StateWorkFlowStateDiagram

我們來設計個用設計模式中的狀態模式來設計這個工作流。

設計

先看看它的User Case功能設計:

StateWorkFlowUseCaseDiagrarm

再看看它的Class diagram設計:

TestStateWorkflowClassDesignDiagram

 

實現

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

 

查看運行的結果:

image

歡迎各位參與討論,如果覺得對你有幫助,請點擊image    推薦下,萬分謝謝.

作者:spring yang

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

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM