zoukankan      html  css  js  c++  java
  • 用状态模式实现状态机工作流

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

    概述

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

    场景

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

    StateWorkFlowStateDiagram

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

    设计

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

    StateWorkFlowUseCaseDiagrarm

    再看看它的Class diagram设计:

    TestStateWorkflowClassDesignDiagram

    实现

    先创建Enums class:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    /********************************************************************************
    ** 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:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /********************************************************************************
    ** 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /********************************************************************************
    ** 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /********************************************************************************
    ** 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    /********************************************************************************
    ** 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    /********************************************************************************
    ** 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    /********************************************************************************
    ** 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    /********************************************************************************
    ** 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:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    /********************************************************************************
    ** 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    /********************************************************************************
    ** 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    /********************************************************************************
    ** 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/

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

  • 相关阅读:
    今天学习的数组不是很懂
    今天的复习内容
    这是今天的作业
    总结,错误反思
    php 文件读取
    call_user_func函数
    plsql中调试函数 转
    oracle数据库中函数的递归调用
    关闭PdfReader右侧工具栏的方法
    Dev TreeList基本用法
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2958381.html
Copyright © 2011-2022 走看看