我有一个类Document,文档具有一个状态:
public enum DocumentStatus : byte
{
Incompleted,
Completed,
Cancelled
}现在我遇到了一个我无法独自解决的难题。
Document应该有像Cancel和Complete这样的方法,以及像DocumentCancelled和DocumentCompleted这样的域事件吗?
public class Document : Entity, IAggregateRoot
{
...
public DocumentStatus Status { get; private set; }
public void Cancel()
{
Status = DocumentStatus.Cancelled;
this.AddDomainEvent(new DocumentCancelled(this));
}
public void Complete()
{
Status = DocumentStatus.Completed;
this.AddDomainEvent(new DocumentCompleted(this));
}
}或者让Status设置器公开并有像DocumentStatusChanged这样的域事件也很好吗?
public class Document : Entity, IAggregateRoot
{
...
private DocumentStatus _status;
public DocumentStatus Status
{
get => _status;
set {
this.AddDomainEvent(new DocumentStatusChanged(this, _status, value)); // oldValue, newValue
_status = value;
}
}
}在本例中,这比使用以下方法更好:
public class Document : Entity, IAggregateRoot
{
...
public DocumentStatus Status { get; private set; }
public void SetDocumentStatus(DocumentStatus status)
{
this.AddDomainEvent(new DocumentStatusChanged(this, Status, status)); // oldValue, newValue
Status = status;
}
}对不起,如果这听起来微不足道或愚蠢,但我是新手DDD,并试图遵循最佳实践。
发布于 2018-08-20 19:18:04
文档是否应该有像
Cancel和Complete这样的方法,以及像DocumentCancelled和DocumentCompleted这样的域事件?
如果应用程序不会侦听事件,就不要创建事件。除非您正在处理传统应用程序(即桌面或电话),否则这些事件不会有多大帮助。这些方法是个好主意。它们使文档状态成为一个只读属性,取消或完成文档的行为可以自由地进行其他操作,而不仅仅是设置状态。这是一件好事。
或者让
Status设置器公开并有像DocumentStatusChanged这样的域事件也很好吗?
同样,关于事件的同样的评论。如果您必须添加任何附加逻辑(如验证等)然后,一个简单的setter将使您的代码难以理解。
我要回答的最大问题是,您的领域模型在哪里使用?Web应用程序和标准UI有不同的通信方式。如果您的模型不需要通知任何其他代码,则不需要通知。
还有另一种选择:
class Document : Entity, IAggregateRoot
{
public DocumentStatus Status { get; private set; }
public void Cancel()
{
this.AddDomainEvent(new DocumentStatusChanged(this, Status, DocumentStatus.Cancelled));
Status = DocumentStatus.Cancelled;
}
public void Complete()
{
this.AddDomainEvent(new DocumentStatusChanged(this, Status, DocumentStatus.Completed));
Status = DocumentStatus.Completed;
}
}发布于 2018-08-20 11:59:33
在这种情况下,您可能应该使用您的领域专家的语言作为指南--思考领域建模的一种方法是,我们正在尝试创建一种特定于领域的语言,该语言与我们试图解决的问题相匹配。
很少有域使用"set“作为语言中的头等关注点。
例如,我们“放置”、“完成”和“取消”订单。因此,我们更愿意对这种语言进行建模,而不是使用像"set status“这样的拼写。
发布于 2018-08-20 11:59:46
如果状态之间的所有转换都是有效的,那么我可能只需要使用公共getter + setter创建一个属性,这是最简单的事情,它可以工作,而且几乎不需要代码。
如果某些转换是被禁止的,那么您肯定会想要使用imho方法,例如不能从被取消的->完成
https://softwareengineering.stackexchange.com/questions/377145
复制相似问题