我不确定为此使用服务。
据我所知,DDD的原理之一(我现在正在阅读)是域对象组织成聚合,并且当你创建一个聚合根的实例时,它可以只能直接处理Aggregate中的对象(以帮助保持清晰的责任感)。
创建骨料应该执行任何不变量等
隔空Customer类的一个例子,客户可能是聚合根和骨料内的另一个类可能是地址。
现在,如果您要创建新的客户,您应该可以使用客户构造函数或工厂来完成此操作。这样做应该返回在Aggregate边界内完全有效的对象(所以它不能处理产品,因为它们不是Aggregate的一部分,但它可以处理地址)。
数据库是一个次要问题,只有将聚合持久化到数据库或从数据库中检索数据库时才起作用。
为了避免直接与数据库连接,您可以创建一个Repository接口(如上所述),给定一个Customer实例(其中包含对Address的引用)应该能够将Aggregate持久化到数据库。
问题是,Repository接口是你的领域模型/层的一部分(不是库的实现)。另一个因素是版本库可能最终应该调用与创建新对象相同的“创建”方法(以维护不变量等)。如果你使用的是构造函数,这很简单,因为当数据库从数据库“创建”对象时,最终你会调用构造函数。
应用程序层可以直接与域(包括存储库接口)进行通信。
所以,如果你想创建一个对象的新实例,你可以例如
Customer customer = new Customer();
如果应用程序需要检索库中的客户的实例,也没有特别的原因,我能想到的它不叫......
Customer customer = _custRepository.GetById(1)
或...
Customer customer = _custRepository.GetByKey("AlanSmith1")
最终,它将最终得到一个Customer对象的实例,它在它自己的限制和规则内运行,就像直接创建新的Customer对象一样。
我认为服务应该保留,当你试图使用的“东西”只是不是一个对象。大多数规则(约束等)可以写成域对象本身的一部分。
一个很好的例子是在我正在阅读的DDD快速pdf。在那里,他们对书架对象有一个限制,因此只能添加与书架可以包含的书一样多的书。
调用BookShelf对象上的AddBook方法会在将书籍添加到BookShelf的Book对象集合之前检查该空间是否可用。一个简单的例子,但业务规则是由域对象本身强制执行的。
我不是说以上任何一种都是正确的!我正试图让我的头在这一刻!
同意。作为一个例子,我认为它是“OK”,但如果他们提到这不是从架构的角度来看最好的做法,那将会很好。 – 2009-07-30 02:05:56