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

发布于 2024-09-12 01:42:53 字数 684 浏览 6 评论 0原文

我注意到存储库通常通过以下方式实现:

方法 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 对其进行建模。

您对此有何看法?

莫什

I've noticed Repository is usually implemented in either of the following ways:

Method 1

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

Method 2

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

Method 1 has collection semantics (which is how repositories are defined). We can get an object from a repository and modify it. But we don't tell the collection to update it. Implementing a repository this way requires another mechanism for persisting the changes made to an in-memory object. As far as I know, this is done using Unit of Work. However, some argue that UoW is only required when you need transaction control in your system.

Method 2 eliminates the need to have UoW. You can call the Save() method and it determines if the object is new and should be Inserted or is modified and should be Updated. It then uses the data mappers to persist the changes to the database. Whilst this makes life much easier, a repository modeled doesn't have collection semantics. This model has DAO semantics.

I'm really confused about this. If repositories mimic in-memory collection of objects, then we should model them according to Method 1.

What are your thoughts on this?

Mosh

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

桜花祭 2024-09-19 01:42:53

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

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

事实上,存储库使用的术语与数据访问和对象集合非常相似,这导致了混乱。我只是将他们视为自己的一等公民,并做对这个领域最有利的事情。 ;-)

I personally have no issue with the Unit of Work pattern being a part of the solution. Obviously, you only need it for the CUD in CRUD. The fact that you are implementing a UoW pattern, though, does nothing more than dictate that you have a set of operations that need to go as a batch. That is slightly different than saying it needs to be a part of a transaction. If you abstract your repositories well enough, your UoW implementation can be agnostic to the backing mechanism that you are using - whether it is database, XML, etc.

As to the specific question, I think the difference between method one and method two are trivial, if for no other reason than most instances of method two contain a check to see if the identifier is set. If set, treat as update, otherwise, treat as insert. This logic is often built into the repository and is more for simplification of the exposed interface, in my opinion. The repository's purpose is to broker objects between a consumer and a data source and to remove having to have knowledge of the data source directly. I go with method two, because I trust the simple logic of detecting an identifier than having to rely on tracking object states all over the application.

The fact that the terminology for repository usage is so similar to both data access and object collections lend to the confusion. I just treat them as their own first class citizen and do what is best for the domain. ;-)

千と千尋 2024-09-19 01:42:53

也许您希望:

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

“坚持”与“保存或更新”或“添加或更新”相同 - 即。 Repo 封装了创建新身份(数据库可以执行此操作),但始终返回带有身份引用的新实例。

Maybe you want to have:

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

"Persist" being the same as "Save Or Update" or "Add Or Update" - ie. the Repo encapsulates creating new identities (the db may do this) but always returns the new instance with the identity reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文