我正在寻找有关设计合同管理数据模型的建议。因此,合同的一般生命周期为:


合同已创建并且处于“草稿”状态。内部可见,并且可以进行更改。
合同交给供应商,状态设置为“待处理”
合同被卖方拒绝。在这种状态下,合同无能为力。不得将任何状态添加到集合中。
供应商接受合同。在这种状态下,合同无能为力。不得将任何状态添加到集合中。


我显然希望避免发生合同被接受且金额发生变化的情况。这是我的课程:

[EnforceNoChangesAfterDraftState]
public class VendorContract
{
 public virtual Vendor Vendor { get; set; }
 public virtual decimal Amount { get; set; }
 public virtual VendorContact VendorContact { get; set; }
 public virtual string CreatedBy { get; set; }
 public virtual DateTime CreatedOn { get; set; }
 public virtual FileStore Contract { get; set; }

 public virtual IList<VendorContractStatus> ContractStatus { get; set; }
}

[EnforceCorrectWorkflow]
public class VendorContractStatus
{
  public virtual VendorContract VendorContract { get; set; }
  public virtual FileStore ExecutedDocument { get; set; }
  public virtual string Status { get; set; }
  public virtual string Reason { get; set; }
  public virtual string CreatedBy { get; set; }
  public virtual DateTime CreatedOn { get; set; }
}


我省略了filestore类,该类基本上是用于根据其guid查找文档的键/值查找。

在Nhibernate中,将VendorContractStatus映射为多对一。

然后,按照here所述使用自定义验证程序。如果VendorContractStatus集合中返回了除草稿之外的任何内容,则不允许进行任何更改。此外,VendorContractStatus必须遵循正确的工作流程(您可以在挂起后添加拒绝项,但是如果存在拒绝项或接受项,则不能向集合中添加其他任何内容)。

听起来不错吗?一位同事认为,我们应该简单地向VendorContract添加一个“ IsDraft”布尔属性,如果IsDraft为假,则不接受更新。然后,我们应该在VendorContractStatus内设置一个用于更新状态的方法,如果在草稿后添加了某些内容,它将VendorContract的IsDraft属性设置为false。

我不喜欢这样,因为我感觉自己正在弄脏POCO并添加应该保留在验证区域中的逻辑,这些类中不应真正存在任何规则,并且它们不应该知道其状态。

有什么想法,从DDD的角度来看,更好的做法是什么?

我认为,如果将来我们需要更复杂的规则,从长远来看,我的方法将更具可维护性。假设我们有一定数量的合同需要经理批准。我认为与VendorContractApproval类进行一对一映射比添加IsApproved属性要好,但这只是猜测。

这也许让人费劲,但这是我们完成的第一个真正的坚韧的企业软件项目。任何意见,将不胜感激!

最佳答案

有两件事要考虑;

1)您是否真的希望合同请求和有效合同使用相同的对象模型。他们不会将不同的用例应用于他们吗?

2)如果确实要使用同一对象,则最好使用state pattern控制哪些操作对于当前状态有效。

08-18 21:57