状态模式主要解决当控制一个对象状态的转换的条件表达过于复杂的情况,使得状态的转换不依赖于整体的操作。本文将通过一个具体的例子说明状态模式的应用。假设下面一个场景:
一个新任务提交后,先是收集数据,数据收集完成后等等分配一台机器,分配到机器后就可以将此任务部署至此机器后就可以通知相关模块开始工作。
先对此场景做分析如下:
一个任务共分四个步骤:一收集数据,二分配机器,三部署到测试机,四通知相关对象。
任务的状态可以分为:new, waiting, Ready, Running分别对应新任务提交,等待分配机器,准备部署,和部署完成于上面的步骤一一对应。
定义一个任务类:
1: /*abstract*/ class Task : IGatherData, IAllotMachine, IDeployTestManchine, INotifyUser // 这里是分别为以上四个步骤定义的接口
2: {
3:
4: // 任务在数据库里对应的ID
5: private string taskIdInDataTable;
6: public string TaskIdInDataTable
7: {
8: get
9: {
10: return taskIdInDataTable;
11: }
12: set
13: {
14: taskIdInDataTable = value;
15: }
16: }
17:
18: // 任务的状态
19:
20: private TaskState _TaskState;
21: public TaskState TaskState
22: {
23: get
24: {
25: return _TaskState;
26: }
27:
28: set
29: {
30: _TaskState = value;
31: Log.Info("当前状态:" + _TaskState.GetType().Name);
32: }
33: }
34:
35: public Task()
36: {
37: this._TaskState = new NewTaskState();
38: }
39:
40: // 可以指定一个任务的当前状态
41:
42: public UpDateTask(TaskState taskTask)
43: {
44: this._TaskState = taskTask;
45: }
46:
47: /// <summary> 改变一个任务的状态至当前任务的下一个状态
48: /// </summary>
49: public void ChangeState()
50: {
51: System.Threading.Thread.Sleep(500);
52: this._TaskState.ChangeState(this);
53: }
54:
55: /// 以下是实现接口中的方法
56: /// 合并数据
57: public virtual bool gatherData()
58: {
59:
60: return true;
61: }
62:
63: /// 分配机器
64: /// 分配机器放在基类里面做,因为这个动作对每个任务来说基本都是一样的
65: public virtual bool allotMachine()
66: {
67: DoWork work = new DoWork();
68:
69: return work.allotMachine(this.taskIdInDataTable);
70: }
71:
72:
73: /// 部署至测试机
74: /// 部署至测试机放在基类里面做,因为这个动作对每个任务来说基本都是一样的
75: public virtual bool deployTestManchine()
76: {
77: DoWork work = new DoWork();
78:
79: return work.deployTestManchine(this.taskIdInDataTable);
80: }
81:
82: /// 通知相关人员
83:
84: /// 通知相关人员放在基类里面做,因为这个动作对每个任务来说基本都是一样的
85: public virtual bool deployTestManchine()
86: {
87: DoWork work = new DoWork();
88:
89: return work.deployTestManchine(this.taskIdInDataTable);
90: }
91:
92: }
93:
94: 此我们的任务类已经定义完成,其中有一个ChangeState的方法,此方法负责调用状态类的改变状态的方法。
95:
96: 下面就写Status类:
97:
98: 是定义一个超类,此类只有一个方法就是ChangeState, 此方法负责控制任务状态的转换。
99:
100: bstract class TaskState
101: {
102: /// <summary>状态改变过程
103: /// </summary>状态的改变由统一的接口进行从一个状态到下一下状态的改变,
104: /// 使用时不用关心内部的状态是怎么改变的,只需统一调用此方法即可。
105: /// <param name="task"></param>
106: public abstract void ChangeState(UpDateTask task);
107: }
108:
109: 面定义具体的状态类:
110: