我正在尝试实现DDD,所以我创建了以下类
- 用户[域名模型]
- UserRepository [管理对象的中央工厂]
- UserMapper + UserDbTable [用于映射应用程序功能并提供CRUD实现的Mapper]
我的第一个问题是,当模型需要与持久层进行通信时,它是否应该与存储库或映射器联系?就我个人而言,我认为它应该询问将与映射器联系并提供所需功能的存储库。
现在我的第二个问题是,同一个类的所有对象应该只有一个存储库,这意味着我将创建一个单例。但如果我的应用程序有很多域模型(比方说20),那么将有20个单身人士。它感觉不对。另一种选择是使用DI(依赖注入),但我使用的框架(Zend Framework 1.11)不支持DIC。
我的第三个
答案 0 :(得分:6)
- UserRepository [管理对象的中央工厂]
在DDD Repository中不是Factory。存储库负责域对象的中间和寿命结束。工厂负责开始。从概念上讲,持久化和恢复在其中间生活中发生在域对象中。
- UserMapper + UserDbTable [映射应用程序功能并提供CRUD实现的Mapper]
这些类不属于域层,这是数据访问。它们都将被存储库实现封装(或者如果使用ORM则根本不存在)。
我的第一个问题是当一个模型需要与之沟通时 持久层应该联系Repository还是映射器? 我个人认为它应该询问存储库哪个会 联系映射器并提供所需的功能。
模型不需要与持久层通信。实际上,您应该尝试使模型尽可能与持久性无关。从您的域模型的角度来看,Repository只是一个接口。该接口的实现属于不同的层 - 数据访问。稍后将在Application层的某个位置注入实现。应用层知道持久性和事务。您可以在此处实现Unit Of Work模式(也不属于域层)。
现在我的第二个问题是,同一个类的所有对象应该只有一个存储库,这意味着我将创建一个单例。但如果我的应用程序有很多域模型(比方说20),那么将有20个单身人士。
首先,您可以拥有给定域对象的more than one存储库。这是大多数时候发生的事情,因为你想避免Repository接口上的'方法爆炸'。其次,单例存储库是一个坏主意,因为它会将所有消费者耦合到单个实现,其中包括使单元测试变得困难。第三,拥有20个或更多存储库没有任何问题,实际上你拥有的聚焦类越多越好,请参阅SRP。
更新:
我认为您正在混淆常规工厂模式和DDD工厂。在DDD术语中,当从数据库恢复对象时,它已经在概念上存在(即使它是内存中的新对象)。因此,存储库有责任持久化并恢复它。当复杂域对象开始生命时,DDD工厂开始发挥作用 - 无论它是否是长期存在的对象(保存在db中)。
答案 1 :(得分:1)