使用域驱动设计时,您的服务方法是否更好地将实体作为参数或实体的id作为参数接收,以便您可以使用存储库检索方法内的实体?
例如:
public void Apply(Job job, User user)
与
public void Apply(int jobId, int userId)
答案 0 :(得分:7)
DDD是关于将客户的词汇量映射到您的设计。您的客户(希望)谈论申请工作的用户,而不是某个整数ID链接到另一个整数ID。尝试尽可能接近坚持现实世界,除非它成为负担。
通过传递整个实体,您可以立即从实体的行为中受益,而无需先构建它。
所以坚持使用实体,除非你的经常只有一个ID可以使用。当您处理外部系统(例如Web服务)时,通常会发生这种情况。在这种情况下,您可以创建一个接受ID的方法重载。此重载应验证ID,构造实体并调用接受实体的重载。
public void Apply(int jobId, int userId)
{
// Validate the IDs.
// Construct the entities.
var job = ...;
var user = ...;
// Call the 'proper' overload.
Apply(job, user);
}
public void Apply(Job job, User user)
{
// Actual business logic belongs here.
}
再次:尝试尽可能避免此类重载,除非您正在处理仅返回ID的外部系统。
从编码的角度来看,实体也比整数更好。整数可以是任何整数值,因此您必须在使用它的任何地方对其进行验证。您的工厂负责构建有效实体,您的(域)逻辑应使您的实体保持有效状态。因此,使用该实体是完全安全的,不需要太多验证。
答案 1 :(得分:4)
这取决于 您的应用服务所在的位置:
如果您的服务在相同的AppDomain 内执行(即您从同一个可执行文件中调用它),则传递该对象是理想的选择。服务可以轻松访问对象图中的其他对象。
如果您的服务在不同的AppDomain 中执行(例如在WebService或其他远程位置后面),则应使用ID。然后,服务将在使用之前从持久性存储加载适当的对象。
如果您尝试向下发送对象,则可能会遇到problems described here。
希望有所帮助。
答案 2 :(得分:1)
如果发送对象,则表示您正在创建服务与实体之间的依赖关系。使用服务的一个优点是充当外观以减少类之间的依赖图并降低设计的复杂性。最好在服务契约中使用原始类型,结构,枚举,但在处理大量方法参数时,您可以将它们封装在一个对象中,但在这种情况下,它将是一个DTO而不是一个实体。
答案 3 :(得分:1)
我使用ViewModel将“平面实体”传递给应用程序服务或从应用程序服务传递。我还使用Document Message模式与应用程序服务进行通信。在应用程序服务中,对业务实体使用扩展方法,如下所示:
public BusinessEntityViewModel ConvertToViewModel(this BusinessEntity businessEntity)
{
BusinessEntityViewModel bevm = new BusinessEntityViewModel{ Id = businessEntity.Id, ...}
return bevm;
}
答案 4 :(得分:0)
根据我的理解,差异只是Domain使用User和Job进行“Apply”操作的事实。如果ID足够,那么只留下ID。