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

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

概述

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

场景

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

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/

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

原文地址:https://www.cnblogs.com/Leo_wl/p/2958381.html