DDD:存储库是对象的内存中集合?

时间:2010-08-02 03:52:50

标签: repository domain-driven-design repository-pattern ddd-repositories

我注意到Repository通常采用以下任一方式实现:

方法1

void Add(object obj);
void Remove(object obj);
object GetBy(int id); 

方法2

void Save(object obj);     // Used both for Insert and Update scenarios
void Remove(object obj);
object GetBy(int id);

方法1具有集合语义(即存储库的定义方式)。我们可以从存储库中获取对象并进行修改。但是我们不会告诉集合更新它。以这种方式实现存储库需要另一种机制来持久保存对内存中对象所做的更改。据我所知,这是使用工作单元完成的。但是,有些人认为只有在系统中需要事务控制时才需要使用UoW。

方法2消除了使用UoW的需要。您可以调用Save()方法,它确定对象是否为新对象,应该是Inserted还是已修改,应该更新。然后,它使用数据映射器将更改持久保存到数据库中。虽然这使生活更容易,但建模的存储库没有集合语义。该模型具有DAO语义。

我真的很困惑。如果存储库模仿内存中的对象集合,那么我们应该根据方法1对它们进行建模。

您对此有何看法?

MOSH

2 个答案:

答案 0 :(得分:2)

我个人对工作单元模式是解决方案的一部分没有任何问题。显然,你只需要CRUD中的CUD。但是,您实现UoW模式的事实只不过是要求您拥有一组需要批量运行的操作。这与说需要成为交易的一部分略有不同。如果您足够好地抽象您的存储库,您的UoW实现可以与您正在使用的支持机制无关 - 无论是数据库,XML等。

关于具体问题,我认为方法一和方法二之间的区别是微不足道的,如果没有其他原因,方法二的大多数实例都包含检查是否设置了标识符。如果设置,则视为更新,否则,视为插入。在我看来,这个逻辑通常内置在存储库中,更多的是为了简化暴露的接口。存储库的目的是在消费者和数据源之间代理对象,并且必须直接了解数据源。我使用方法二,因为我相信检测标识符的简单逻辑,而不是依赖于遍布应用程序的跟踪对象状态。

存储库使用术语与数据访问和对象集合类似的事实导致了混淆。我只是将他们视为自己的一等公民,并为域名做最好的事情。 ; - )

答案 1 :(得分:1)

也许你想拥有:

T Persist(T entityToPersist);
void Remove(T entityToRemove);

“持久”与“保存或更新”或“添加或更新”相同 - 即。 Repo封装了创建新身份(db可能会这样做),但总是返回带有身份引用的新实例。