{
// 任务在数据库里对应的ID
private string taskIdInDataTable;
public string TaskIdInDataTable
{
get
{
return taskIdInDataTable;
}
set
{
taskIdInDataTable = value;
}
}
// 任务的状态
private TaskState _TaskState;
public TaskState TaskState
{
get
{
return _TaskState;
}
set
{
_TaskState = value;
Log.Info("当前状态:" + _TaskState.GetType().Name);
}
}
public Task()
{
this._TaskState = new NewTaskState();
}
// 可以指定一个任务的当前状态
public UpDateTask(TaskState taskTask)
{
this._TaskState = taskTask;
}
/// summary 改变一个任务的状态至当前任务的下一个状态
/// /summary
public void ChangeState()
{
System.Threading.Thread.Sleep(500);
this._TaskState.ChangeState(this);
}
/// 以下是实现接口中的方法
/// 合并数据
public virtual bool gatherData()
{
return true;
}
/// 分配机器
/// 分配机器放在基类里面做,因为这个动作对每个任务来说基本都是一样的
public virtual bool allotMachine()
{
DoWork work = new DoWork();
return work.allotMachine(this.taskIdInDataTable);
}
/// 部署至测试机
/// 部署至测试机放在基类里面做,因为这个动作对每个任务来说基本都是一样的
public virtual bool deployTestManchine()
{
DoWork work = new DoWork();
return work.deployTestManchine(this.taskIdInDataTable);
}
/// 通知相关人员
/// 通知相关人员放在基类里面做,因为这个动作对每个任务来说基本都是一样的
public virtual bool deployTestManchine()
{
DoWork work = new DoWork();
return work.deployTestManchine(this.taskIdInDataTable);
}
}
到此我们的任务类已经定义完成,其中有一个ChangeState的方法,此方法负责调用状态类的改变状态的方法。
接下面就写Status类:
先是定义一个超类,此类只有一个方法就是ChangeState, 此方法负责控制任务状态的转换。
abstract class TaskState
{
/// summary状态改变过程
/// /summary状态的改变由统一的接口进行从一个状态到下一下状态的改变,
/// 使用时不用关心内部的状态是怎么改变的,只需统一调用此方法即可。
/// param name="task"/param
public abstract void ChangeState(UpDateTask task);
}
下面定义具体的状态类:
// 新任务状态
class NewTaskState: TaskState
{
public override void ChangeState(UpDateTask task)
{
// 检查当前状态
if (this == task.TaskState)
{
if (task.gatherData())
{
task.TaskState = new WaitingTaskState(task);
}
else // 如果合并数据任务失败,将任务打到已清除状态
{
task.TaskState = new DeletedState(task);
}
}
}
public NewTaskState()
{
}
public NewTaskState(UpDateTask task)
{
DoWork.setTaskState(task.TaskIdInDataTable, enumTaskState.NewTask);
}
}
// 等待任务状态
class WaitingTaskState : TaskState
{
public override void ChangeState(UpDateTask task)
{
if (this == task.TaskState)
{
if (task.allotMachine())
{
task.TaskState = new ReadyTaskState(task);
}
else
{
task.TaskState = new WaitingTaskState(task);
}
}
}
public WaitingTaskState()
{
}
public WaitingTaskState(UpDateTask task)
{
DoWork.setTaskState(task.TaskIdInDataTable, enumTaskState.Waiting);
}
}
// 准备任务状态
class ReadyTaskState : TaskState
{
public override void ChangeState(UpDateTask task)
{
if (this == task.TaskState)
{
if (task.deployTestManchine())
{
task.TaskState = new RunningState(task);
}
else
{
// 部署失败则重新分配新的测试机器
task.TaskState = new WaitingTaskState(task);
}
}
}
public ReadyTaskState()
{
}
public ReadyTaskState(UpDateTask task)
{
DoWork.setTaskState(task.TaskIdInDataTable, enumTaskState.Ready);
}
}
// 运行任务状态
class RunningState : TaskState
{
public override void ChangeState(UpDateTask task)
{
// send e-mail
}
public RunningState()
{
}
public RunningState(UpDateTask task)
{
DoWork.setTaskState(task.TaskIdInDataTable, enumTaskState.Running);
}
}
// 下来看客户端调用
Task task = new Task ();
task.TaskIdInDataTable = 1111; // 为此任务指定一个ID
下来就最重要的,做了这么多事就是为了下面的调用:
task.ChangeState();
task.ChangeState();
task.ChangeState();
task.ChangeState();
这样此任务就完成了,客户端根本不用关心任务的状态是怎么转换的,因为每一个状态的转换都是由当前的状态决定自己的下一个状态是什么,即使要修改状态的流程也只需要修改状态类就可以,也不用关心具体的操作。这样做很方便的将状态转换、任务的具体步骤、与客户端的调用分开,之间不受影响。
也可以指定一个任务的当前状态,从此状态开始,比如可以指定此任务从Wating开始,此任务就会从Waiting对应的allotMachine开始运行:
Task task = new Task (new WaitingTaskState);
到此状态模式的应该已全部写完。