存储库模式 - 如何理解它以及它如何与“复杂”实体? [英] Repository Pattern - How to understand it and how does it work with "complex" entities?

查看:177
本文介绍了存储库模式 - 如何理解它以及它如何与“复杂”实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解Repository Pattern。



关于这个话题有很多意见,如版本库模式完成正确,但也有其他的东西,如 Repository是新的Singleton ,或者再次类似于不要使用DAO使用Repository ,或者只是使用 Spring JPA Data + Hibernate + MySQL + MAVEN 在某种程度上,Repository似乎与DAO对象相同。



自从imho读取这些东西后,我感到厌倦,这不可能是如此困难因为它显示在很多文章中。



我看到它是这样的:看起来我想要的是这样的:

  -------- -------------------------------------------------- -------------- 
|服务器|
---------------------------------------------- --------------------------
| | | |
客户端< - | - >服务层< - | - >储存库层< - | - > ORM /数据库层|
| | | |
---------------------------------------------- --------------------------

服务层 * DTO 对象并将其传递给存储库Layer 基本上只不过是知道一个实体如何存储的人。



例子假设你有一些工具的组合(请注意,这只是伪代码

  @Entity 
class ToolSet {
@Id
public Long id;
@OneToOne
public Tool tool1;
@OneToOne
public Tool tool2;
}

@Entity
class工具{
@Id
public Long id;
@OneToMany
public ToolDescription toolDescription;
}

@Entity
class ToolDescription {
@Id
public Long id;
@NotNull
@OneToOne
public语言语言

public String name;
public String details;
}

我没有得到的东西是我得到 ToolSetDTO 对象来自客户端。



据我了解,到目前为止我可以编写一个 ToolSetRepository 使用方法 ToolSetRepository.save(ToolSetDTO toolSetDto)表示知道如何存储a ToolSetDTO 。但几乎每个教程都不会传递 * DTO ,而是实体。



这里有什么让我困扰的是,如果您从上面获取我的 ToolSet 示例,则必须执行以下步骤:


  1. toolSetDto 并检查是否 null

  2. 对于每个工具* Dto ,归属于 toolSetDto
    a)If然后从 DTO 转换为实体,否则创建一个新的数据库条目。b) toolDescriptionDto 并将其转换/保存到数据库或创建一个新条目
  3. 在检查了上面的实例 ToolSet
  4. code>(entity)并将其设置为将其保存在数据库中

所有这些过于复杂,不能简单地让服务功能(客户端接口)处理这个问题。



我在想的是创建例如一个 ToolSetRepository 但这里的问题是


  • 是否需要一个 ToolSet 实体对象还是使用 DTO 对象?

  • 无论如何:是 * Repository 允许使用其他资源库对象?就像我想要保存 ToolSet 但我必须存储工具 ToolDescription 首先 - 我会在 ToolSetRepository中使用 ToolRepository ToolDescriptionRepository
    如果是这样的话:为什么它不会破坏Repository Pattern?如果这个模式基本上是服务和我的ORM框架之间的一个层,那么由于依赖性的原因,向其他 * Repository 类添加依赖关系并不正确。



我不知道为什么我无法理解这一点。这听起来并不复杂,但仍然有帮助,比如 Spring Data 。另一件令我烦恼的事情是因为我真的没有看到这使得 变得更容易。特别是因为我已经使用Hibernate了 - 我没有看到好处(但也许这是另一个问题)。
$ b $所以..我知道这是一个很长的问题,但我已经进行了几天的研究。我现在正在使用的代码已经开始变得混乱,因为我无法看穿这个模式。



我希望有人能给我一个更大的图片比大多数的文章和教程没有超出实现一个非常简单的Repository Pattern例子。

你可以阅读我的假人库发布以了解存储库的简单原则。我认为你的问题在于你正在使用DTO,在这种情况下,你并没有真正使用存储库模式,你正在使用DAO。



存储库和dao之间的主要区别在于存储库仅返回被调用层理解的对象。大多数情况下,存储库由业务层使用,因此它会返回业务对象。 dao返回的数据可能是也可能不是整个业务对象,即数据不是一个有效的业务概念。



如果您的业务对象只是数据结构,可能是一个提示,你有一个建模问题,即糟糕的设计。存储库通过丰富或至少适当封装的对象更有意义。如果你只是加载/保存数据结构,可能不需要存储库,那么orm就足够了。



如果您要处理的业务对象由其他对象(聚合),并且该对象需要它的所有部分才能一致(聚合根),那么存储库模式是最好的解决方案,因为它会抽象所有持久性细节。您的应用程序只需要一个'产品',并且存储库会将其作为一个整体返回,无论需要多少表或查询来恢复该对象。



基于在您的代码示例中,您没有真正的业务对象。你有Hibernate使用的数据结构。业务对象是基于业务概念和用例而设计的。该存储库使BL有可能不关心该对象如何被持久保存。从某种意义上说,存储库可以充当对象和模型之间的转换器/映射器,它将被持久化。基本上,回购会将对象减少到持久性数据所需的对象。



业务对象不是 ORM实体。它可能从技术角度来看,一个设计pov,一个模型业务的东西,其他模型持久性的东西。在很多情况下,这些并不直接兼容。

最大的错误是根据存储需求和思维设计您的业务对象。与许多开发人员认为的相反,ORM的目的不是坚持业务对象。其目的是模拟rdbms上的'oop'数据库。 ORM映射位于数据库对象和表之间,而不是应用程序对象(处理业务对象时更少)和表格之间。

I'm having a hard time understanding the Repository Pattern.

There are a lot of opinions on that topic like in Repository pattern done right but also other stuff like Repository is the new Singleton or again like in Don't use DAO use Repository or just take Spring JPA Data + Hibernate + MySQL + MAVEN where somehow a Repository appears to be the same as a DAO object.

I'm getting tired of reading this stuff since imho this can't be such a hard thing as it is displayed in a lot of articles.

I see it like this: It appears that what I want is something like this:

         ------------------------------------------------------------------------
         |                            Server                                    |
         ------------------------------------------------------------------------
         |                    |                        |                        |
Client <-|-> Service Layer  <-|->  Repository Layer  <-|-> ORM / Database Layer |
         |                    |                        |                        |  
         ------------------------------------------------------------------------

The Service Layer takes *DTOobjects and passes those to the Repository Layer that basically is nothing more than "the guy" who knows how an entity can be stored.

For example assume you have a composition of some tools (please note that this is just pseudo code)

@Entity
class ToolSet {
  @Id
  public Long id;
  @OneToOne
  public Tool tool1;
  @OneToOne
  public Tool tool2;
}

@Entity
class Tool {
  @Id
  public Long id;
  @OneToMany
  public ToolDescription toolDescription;
}

@Entity
class ToolDescription {
  @Id
  public Long id;
  @NotNull
  @OneToOne
  public Language language

  public String name;
  public String details;
}

The thing I'm not getting is the part where I am getting a ToolSetDTO object from the client.

As I understood it so far I could write a ToolSetRepository with a method ToolSetRepository.save(ToolSetDTO toolSetDto) that "knows how to store" a ToolSetDTO. But almost every tutorial does not pass the *DTO but the Entity instead.

What's bothering me here is that if you take my ToolSet example from above I'd have to do the following steps:

  1. Take toolSetDto and check if not null
  2. For each tool*Dto owned by toolSetDto
    a) If has a valid id then convert from DTO to Entity otherwise create a new database entry
    b) toolDescriptionDto and convert/save it to the database or create a new entry
  3. After checking those above instanciate ToolSet (entity) and set it up for persisting it in the database

All this is too complex to simply let the service function (interface for the client) handle this.

What I was thinking about was creating e.g. a ToolSetRepository but the question here is

  • Does it take a ToolSet entity object or does it use a DTO object?
  • In any case: Is the *Repository allowed to use other repository objects? Like when I want to save ToolSet but I have to store Tool and ToolDescription first - would I use ToolRepository and ToolDescriptionRepository inside ToolSetRepository?
    If so: Why doesn't it break the Repository Pattern? If this pattern is basically a layer between the service and my ORM framework it just does not "feel right" to add dependencies to other *Repository classes due to dependency reasons.

I don't know why I can't get my head around this. It does not sound that complicated but there's still help out there like Spring Data. Another thing that is bothering me since I really don't see how this makes anything easier. Especially since I'm using Hibernate already - I don't see the benefit (but maybe that's another question).

So .. I know this is a long question but I put already a few days of research into it. There's already existing code I am working on right now that starts to become a mess because I just can't see through this pattern.

I hope somebody can give me a bigger picture than most of the articles and tutorials which do not get beyond implementing a very, very simple example of a Repository Pattern.

解决方案

You can read my "repository for dummies" post to understand the simple principle of the repository. I think your problem is that you're working with DTOs and in that scenario, you don't really use the repository pattern, you're using a DAO.

The main difference between a repository and a dao is that a repository returns only objects that are understood by the calling layer. Most of the time the repository is used by the business layer and thus, it returns business objects. A dao returns data which might or might not be a whole business object i.e the data isn't a valid business concept.

If your business objects are just data structures, it might be a hint you have a modeling problem i.e bad design. A repository makes more sense with 'rich' or at least properly encapsulated objects. If you're just loading/saving data structures probably you don't need a repository the orm is enough.

If you're dealing with business objects that are composed from other objects (an aggregate) and that object needs all its parts in order to be consistent (an aggregate root) then the repository pattern is the best solution because it will abstract all persistence details. Your app will just ask for a 'Product' and the repository will return it as a whole, regardless of how many tables or queries are required to restore the object.

Based on your code sample, you don't have 'real' business objects. You have data structures used by Hibernate. A business object is designed based on business concepts and use cases. The repository makes it possible for the BL not to care about how that object is persisted. In a way, a repository acts as a 'converter/mapper' between the object and the model that will be persisted. Basically the repo 'reduces' the objects to the required for persistence data.

A business object is not a ORM entity.It might be from a technical point of view, but from a design pov , one models business stuff the other models persistence stuff. In many cases these are not directly compatible.

The biggest mistake is to design your business object according to storage needs and mindset. And contrary to what many devs believe, an ORM purpose is not to persist business objects. Its purpose is to simulate a 'oop' database on top of a rdbms. The ORM mapping is between your db objects and tables, not between app objects (even less when dealing with business objects) and tables.

这篇关于存储库模式 - 如何理解它以及它如何与“复杂”实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆