2010-01-25 77 views
1

我有一个实体,相当于一个任务,可以有多个状态。 “任务”可以处于未决状态,已通过状态或失败状态。这些州中的每一个也都有一些独特的数据。例如,在失败的状态下,实体应该有失败的原因,在待决状态下它应该有评估的最后期限等。我应该如何建模一个有多个状态的实体?

尽管上面的内容让我想我应该有一个单独的对象来表示每个国家,实体的底层标识都应该保持不变,这促使我将其视为一个单一的对象。

另外,从状态到状态的转换需要一些逻辑。转变为“通过”状态的“未决”任务将与进行相同转换的“失败”任务的处理方式不同。

如果每个状态的表示都完全相同,那么我只是使用一个原始属性并完成它。然而,由于不同的州有不同的表述,我一直在努力找出建模的最佳方法。控制内部状态的逻辑变得有点混乱,所以我想我会退后一步并重新考虑。有什么想法吗?

我使用c#虽然我认为这种语言是不可知的。

回答

1

当我第一次读这个问题时,我的答案是使用枚举来定义状态。重读它之后,虽然,我会建议下列之一:

  1. 落实接受的任何任务每个任务与相同父一个单独的类(PendingTask,PassedTask,...),和构造在该状态之前出现的类型。
  2. 实现一个任务,并用每个状态所需数据的子类创建一个新的TaskStateData类。
  3. 实现一个任务,但有一个单独的方法提供所需要的那种状态

,我建议这些解决方案,以确保数据的完整性额外的属性参数,改州为每个状态类型。

0

看一看在state pattern.

+0

我对这种模式很熟悉。从我的理解以及我如何使用它,它在运行时改变对象的行为是最有帮助的。有了这个问题,我认为,更重要的是管理对象表示的差异。 我可能会在这里一般地咆哮错误的树。解释这个问题帮助我找出了一些不兼容的目标。 – 2010-01-25 17:59:57

0

这听起来像是对象继承和多态的理想应用。

abstract class Task 
{ 
     public int TaskId { get; private set; } 
     abstract PassedTask TransitionToPassed(); 
     ... 
} 

class PendingTask : Task 
{ 
     PassedTask TransitionToPassed() 
     { 
      PassedTask passed = new PassedTask(); 
      passed.TaskId = TaskId; 
      ... 
      return passed; 
     } 
     ... 
} 

class PassedTask : Task 
{ 
     PassedTask TransitionToPassed() 
     { 
      return this; 
     } 
     ... 
} 

class FailedTask : Task 
{ 
     public string ReasonForFailure { get; private set; } 
     PassedTask TransitionToPassed() 
     { 
      ... 
     } 
     ... 

} 
1

使用纯粹的面向对象的方法有缺点。除非您计划不得不做大量的多态代码管理,否则请避免直接使用多态性来表示域类的状态。我已经解决了一个更混合的方法。需要将不同的状态建模为单独的父/子继承树。从具有MyState1,MyState2和MyState3的抽象基类MyState开始。 (参见Jeffrey's answer举例

需要跟踪其状态的实体具有属于“当前状态”的属性,该属性的类型为MyState当实体更改状态时,它是一个简单的赋值或setter()调用来更改如果需要的话,你可以构造每个状态的单例实例,或者为每个状态变化构造新的实例,这取决于状态改变的频率以及有多少对象状态被跟踪,如果数字变得太大,你可以考虑单例方法

1

“任务”可以处于未决状态,已通过状态或失败状态。 转换为“已通过”状态的“未决”任务将与进行相同转换的“失败”任务的处理方式不同。

这似乎是一个相当奇怪的国家集合。我期望一个任务需要一些时间来执行,因此从挂起转换到执行然后是通过或失败,以及在时间耗尽到期之前不执行的任务。如果还有一个从失败到失败并过期的转换,那么可能会添加另一个状态。

画一个状态机来查找状态。

首先,你需要在结构上模拟状态吗?挂起/过期标志,预定时间和结果是否会(作为结果的两个子类型失败并成功)?这项任务的客户需要什么?

其次,你是否正在与任务或调度程序进行交互?向调度程序提供任务描述并找回未来可能会查询有关任务结果的情况并不少见。但是任务本身并没有暴露,只是它是完整的和结果。如果你需要进步,你可能希望有一个调度程序,可以通过任务ID来查询进度,而不是一个任务对象,你有一个引用 - 有一个任务对象同时改变状态,很难得到一致的集合的状态数据,直到达到最终状态。如果'通过'状态没有失败信息,那么查询'你失败',然后'取得失败状态'容易导致竞争,除非你外部锁定(ewww),所以返回一个不可变的任务状态信息对象原子地变成可取的是,此时你的任务对象变得或多或少等于传递给调度器的ID。

相关问题