关于存储库的域驱动设计问题

Bry*_*yan 2 singleton domain-driven-design dependency-injection zend-framework

我正在尝试实现DDD,所以我创建了以下类
- 用户[域模型]
- UserRepository [管理对象的中央工厂]
- UserMapper + UserDbTable [映射应用程序功能的Mapper并提供CRUD实施]

我的第一个问题是,当模型需要与持久层进行通信时,它是否应该与存储库或映射器联系?就我个人而言,我认为它应该询问存储库,它将与映射器联系并提供所需的功能.

现在我的第二个问题是,同一个类的所有对象应该只有一个存储库,这意味着我将创建一个单例.但如果我的应用程序有很多域模型(比方说20),那么将有20个单身人士.它感觉不对劲.另一种选择是使用DI(依赖注入),但我使用的框架(Zend Framework 1.11)不支持DIC.

我的第三个

Dmi*_*try 6

  • UserRepository [管理对象的中央工厂]

在DDD Repository中不是工厂.存储库负责域对象的中间和寿命结束.工厂负责开始.从概念上讲,持久化和恢复在其中间生活中发生在域对象中.

  • UserMapper + UserDbTable [用于映射应用程序功能并提供CRUD实现的Mapper]

这些类不属于域层,这是数据访问.它们都将被存储库实现封装(或者如果使用ORM则根本不存在).

我的第一个问题是,当模型需要与持久层进行通信时,它是否应该与存储库或映射器联系?就我个人而言,我认为它应该询问存储库,它将与映射器联系并提供所需的功能.

模型不需要与持久层通信.实际上,您应该尝试使模型尽可能与持久性无关.从您的域模型的角度来看,Repository只是一个接口.该接口的实现属于不同的层 - 数据访问.稍后将在Application层的某个位置注入实现.应用层知道持久性和事务.这是您可以实现工作单元模式(也不属于域层)的地方.

现在我的第二个问题是,同一个类的所有对象应该只有一个存储库,这意味着我将创建一个单例.但如果我的应用程序有很多域模型(比方说20),那么将有20个单身人士.

首先,您可以为给定的域对象拥有多个存储库.这是大多数时候发生的事情,因为你想避免Repository接口上的'方法爆炸'.其次,单例存储库是一个坏主意,因为它会将所有消费者耦合到单个实现中,除其他外,这将使单元测试变得困难.第三,拥有20个或更多存储库没有任何问题,实际上你拥有的聚焦程度越高,请参阅SRP.

更新:

我认为你混淆了常规工厂模式和DDD工厂.在DDD术语中,当从数据库恢复对象时,它已经在概念上存在(即使它是内存中的新对象).因此,存储库有责任持久化并恢复它.DDD Factory在复杂域对象开始生命时发挥作用 - 无论它是否是长期存在的对象(保存在db中).