【问题标题】:Service contracts vs. domain objects服务契约与领域对象
【发布时间】:2011-10-21 08:19:03
【问题描述】:
假设我的应用程序有两个接口:
它们都与 Web 服务通信,而该 Web 服务又处理业务逻辑并与一个单独的数据层进行通信,该数据层保存对象。
那么,如果 Web 服务的每个客户端都使用该 Web 服务的 DataContract,我需要域对象来做什么?
领域驱动设计在哪里适合,它给我的架构带来什么优势?
或者是我已经拥有的东西很好,我根本不需要域对象?
我是否误解了领域驱动设计的含义和目的?
【问题讨论】:
-
“我是否误解了领域驱动设计的含义和目的?” Yes :)
标签:
wcf
domain-driven-design
domain-object
datacontracts
【解决方案1】:
我需要域对象做什么?
您的应用程序中可能不需要域对象。通常,DDD 将通过以下方式融入服务层:服务层公开其操作合约和数据合约。数据契约类通常对应于域中的对象,但它们不是域对象,因为它们没有任何行为,它们只是特定服务所关注的数据的表示。以下是服务中数据契约对象和域对象之间的简单交互示例:
public MyEntityDto GetMyEntity(string id) {
var entity = this.myEntityRepository.Get(id);
if (entity == null)
return null;
return new MyEntityDto(entity);
};
在这种情况下,MyEntityDto 是 MyEntity 的 DTO 对象,它用于公开服务希望向其客户提供的 MyEntity 的特定属性。
当您的域更复杂并具有相关行为时,DDD 的价值就会发挥作用:
class MyEntity {
public void ChangeState(MyEntityState state) {
if (!IsValidState(state))
throw new Exception("Not a valid state.");
// further domain logic here...
}
}
[DataContract]
class ChangeStateCommand {
[DataMember]
public string MyEntityId { get; set; }
[DataMember]
public string State { get; set; }
}
public void Process(ChangeStateCommand command) {
var entity = this.myEntityRepository.Get(command.MyEntityId);
if (entity == null)
throw new SomeException().
entity.ChangeState(command.State);
this.myEntityRepository.Commit();
}
在这种情况下,我的 ChangeStateCommand 携带的数据用于对您的域实体进行操作。
【解决方案2】:
数据契约只不过是您的客户端和服务器之间相互交换的消息。
您的 WCF 服务是接受消息并处理它们以便您的业务逻辑可以处理它们的层。
您的域对象将是您的业务逻辑,它接受已处理的消息、执行必要的操作,然后应用需要应用的任何事件。
如果您遵循更多Command-Query Separation 原则 (CQS),那么您的命令(插入/更新/删除)将被触发到 WCF 服务并且不会返回任何内容。您的客户端将请求从您的 WCF 服务读取与您的命令分开(这意味着 InsertOrder 命令不会返回订单 - 您必须为此发出单独的请求)。
在所有这些中,您的数据合同是往返于 WCF 服务的消息。您的域在该服务的背后处理所有需要发生的业务逻辑,以使您的读取尽可能准确。
我更多是从 CQRS(命令-查询职责分离)的角度来回答这个问题,但我希望这能解释我的出发点。
要回答您的其他问题:
- 你需要域对象吗--> 我会说是的,你应该