2

我注意到库通常在以下任一方式实现:DDD:存储库是内存中的对象集合吗?

方法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()方法,并确定对象是否是新的,并且应该插入或修改,并且应该更新。然后它使用数据映射器将更改持久化到数据库。虽然这使生活变得更容易,但建模的存储库不具有集合语义。这个模型有DAO语义。

我对此非常困惑。如果存储库模仿内存中对象的集合,那么我们应该按照方法1对它们进行建模。

您对此有何看法?

MOSH

+0

我使用第一个选项,我很满意它。我目前正在使用NHibernate,所以UoW是免费的。 – goenning 2011-11-17 15:50:00

回答

2

我个人有与工作模式作为解决方案的一部分单位没有问题。很明显,你只需要它在CRUD中的CUD。然而,你正在实现一个UoW模式的事实,只不过是指示你有一组操作需要作为批处理去执行。这与说需要成为交易的一部分略有不同。如果你足够好地抽象你的仓库,你的UoW实现可以不知道你正在使用的支持机制 - 无论是数据库,XML等。

至于具体问题,我认为方法一和方法二很简单,如果除了方法二的大多数实例都包含检查标识符是否设置的其他原因以外。如果设置,则视为更新,否则视为插入。在我看来,这个逻辑经常被内置到资源库中,更多的是简化了暴露的界面。存储库的目的是在消费者和数据源之间代理对象,并删除必须直接了解数据源的知识。我使用方法二,因为我相信检测标识符的简单逻辑,而不必依赖跟踪整个应用程序中的对象状态。

资源库使用术语与数据访问和对象集合非常相似这一事实可能导致混淆。我只是把他们当作他们自己的第一位公民,并且为这个领域做最好的事情。 ;-)

1

也许你想有:

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

“坚持”是一样的“保存或更新”或“添加或更新” - 即。回收封装创建新的身份(数据库可能会这样做),但总是返回带有身份引用的新实例。