如何设计处理(真实)合同的数据模型?

时间:2010-03-30 16:50:08

标签: c# nhibernate domain-driven-design

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

  • 合同已创建且处于“草稿”状态。它可以在内部查看,也可以进行更改。
  • 合同退出供应商,状态设置为“待定”
  • 合同被供应商拒绝。在这种状态下,合同无法进行。系统中不能添加任何状态。
  • 供应商接受合同。在这种状态下,合同无法进行。系统中不能添加任何状态。

我显然希望避免合同被接受的情况,比如金额被改变。这是我的课程:

[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查找文档。

VendorContractStatus在Nhibernate中被映射为多对一。

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

所有声音都好吗?一位同事认为我们应该简单地向VendorContract添加一个“IsDraft”bool属性,如果IsDraft为false,则不接受更新。然后我们应该在VendorContractStatus中设置一个方法来更新状态,如果在草稿之后添加了某些东西,它会将VendorContract的IsDraft属性设置为false。

我不喜欢这样,因为我觉得我弄乱了POCO并添加了应该在验证区域中存在的逻辑,这些类中不应该存在任何规则,并且他们不应该知道它们的状态。

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

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

这可能是分裂,但这是我们已经完成的第一个真正的坚韧不拔的企业软件项目。任何建议将不胜感激!

3 个答案:

答案 0 :(得分:1)

要考虑的两件事情;

1)您是否真的想要合同请求和有效合同的相同对象模型。难道他们不会有不同的用例适用于他们吗?

2)如果你确实想要使用同一个对象,这可能是一个很好的例子,可以使用state pattern来控制哪些动作对当前状态有效。

答案 1 :(得分:0)

在调用者尝试持久化VendorContract实例之前不会强制执行规则这一事实可能会使错误更容易发生,并且使这些类更难使用,因为它们没有描述自己的行为或约束。

通过专注于单一功能来换句话说:被拒绝和接受的合同甚至不应该有Amount的设置访问者。

听起来您可能正朝着anemic domain model(有时以较不偏见的名称'persistent model'所知),其中您的域对象只是没有业务逻辑的容器。那是not always a bad thing,但是在具有大量业务逻辑的系统中,风格重复代码并将规则分散到太多对象上,使得理解(以及维护和更改)管理域实体的规则变得非常困难。

答案 2 :(得分:0)

别。编写描述所需行为的测试。当您为所有用例(并重构)编写测试时,数据模型就完成了。

相关问题