it-swarm.com.de

Repository-Muster - Wie ist es zu verstehen und wie funktioniert es mit "komplexen" Entitäten?

Es fällt mir schwer, das Repository-Muster zu verstehen.

Es gibt viele Meinungen zu diesem Thema wie in Repository-Muster richtig gemacht , aber auch andere Dinge wie Repository ist das neue Singleton oder wieder wie in Nicht tun) benutze DAO benutze Repository oder nimm einfach Spring JPA Data + Hibernate + MySQL + MAVEN wobei ein Repository irgendwie dasselbe zu sein scheint wie ein DAO-Objekt.

Ich werde es leid, dieses Zeug zu lesen, da es so schwer sein kann, wie es in vielen Artikeln gezeigt wird.

Ich sehe es so: Es sieht so aus, als ob ich etwas in der Art möchte:

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

Der Service Layer Nimmt *DTO Objekte und übergibt diese an den Repository Layer, Der im Grunde nichts anderes als "der Typ" ist, der wie kennt = eine Entität kann gespeichert werden.

Angenommen, Sie haben eine Zusammenstellung einiger Tools ( Bitte beachten Sie, dass dies nur Pseudocode ist )

@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;
}

Was ich nicht bekomme, ist der Teil, in dem ich ein ToolSetDTO - Objekt vom Client bekomme.

Soweit ich es bisher verstanden habe, konnte ich eine ToolSetRepository mit einer Methode ToolSetRepository.save(ToolSetDTO toolSetDto) schreiben, die " weiß, wie man " eine ToolSetDTO. Aber fast jedes Tutorial übergibt stattdessen nicht den *DTO, Sondern den Entity.

Was mich hier stört, ist, dass ich, wenn Sie mein ToolSet - Beispiel von oben nehmen, die folgenden Schritte ausführen müsste:

  1. Nimm toolSetDto und überprüfe, ob nicht null
  2. Für jeden tool*Dto Im Besitz von toolSetDto
    a) Wenn Sie eine gültige ID haben, konvertieren Sie von DTO nach Entity, andernfalls erstellen Sie einen neuen Datenbankeintrag
    b) toolDescriptionDto und konvertieren/speichern Sie es in die Datenbank oder erstellen Sie einen neuen Eintrag
  3. Nachdem Sie diese überprüft haben, instanziieren Sie ToolSet (Entität) und richten Sie es so ein, dass es in der Datenbank verbleibt

All dies ist zu komplex, um es einfach der Servicefunktion (Schnittstelle für den Client) zu überlassen, dies zu tun.

Was ich darüber nachdachte, war z. a ToolSetRepository, aber die Frage ist hier

  • Nimmt es ein Entitätsobjekt ToolSet oder verwendet es ein Objekt DTO?
  • Auf jeden Fall: Darf *Repository andere Repository-Objekte verwenden? Zum Beispiel, wenn ich ToolSet speichern möchte, aber zuerst Tool und ToolDescription speichern muss - würde ich ToolRepository und ToolDescriptionRepository in ToolSetRepository?
    Wenn ja: Warum wird das Repository-Muster nicht beschädigt? Wenn dieses Muster im Grunde eine Schicht zwischen dem Dienst und meinem ORM-Framework ist, fühlt es sich einfach nicht "richtig" an, Abhängigkeiten zu anderen *Repository - Klassen hinzuzufügen, da dies durch Abhängigkeiten bedingt ist.

Ich weiß nicht, warum ich das nicht verstehen kann. Es klingt nicht dass kompliziert, aber es gibt immer noch Hilfe wie Spring Data. Eine andere Sache, die mich stört, da ich nicht wirklich sehe, wie dies irgendetwas einfacher macht. Vor allem, weil ich Hibernate bereits verwende - ich sehe den Vorteil nicht (aber vielleicht ist das eine andere Frage).

Also, ich weiß, das ist eine lange Frage, aber ich habe bereits ein paar Tage lang nachgeforscht. Es gibt bereits Code, an dem ich gerade arbeite und der sich in ein Chaos verwandelt, weil ich dieses Muster einfach nicht durchschaue.

Ich hoffe, jemand kann mir ein größeres Bild geben als die meisten Artikel und Tutorials, die nicht über die Implementierung eines sehr, sehr einfachen Beispiels eines Repository-Musters hinausgehen.

62
displayname

Sie können mein "Repository für Dummies" lesen post , um das einfache Prinzip des Repository zu verstehen. Ich denke, Ihr Problem ist, dass Sie mit DTOs arbeiten und in diesem Szenario nicht wirklich das Repository-Muster verwenden, sondern ein DAO.

Der Hauptunterschied zwischen einem Repository und einem Dao besteht darin, dass ein Repository nur Objekte zurückgibt, die von der aufrufenden Ebene verstanden werden. In den meisten Fällen wird das Repository von der Business-Schicht verwendet und gibt daher Business-Objekte zurück. Ein Dao gibt Daten zurück, die ein ganzes Geschäftsobjekt sein können oder nicht, d. H. Die Daten sind kein gültiges Geschäftskonzept.

Wenn es sich bei Ihren Geschäftsobjekten nur um Datenstrukturen handelt, kann dies ein Hinweis darauf sein, dass Sie ein Modellierungsproblem haben, z. B. ein schlechtes Design. Ein Repository ist sinnvoller bei "reichen" oder zumindest richtig gekapselten Objekten. Wenn Sie nur Datenstrukturen laden/speichern, benötigen Sie wahrscheinlich kein Repository.

Wenn Sie es mit Geschäftsobjekten zu tun haben, die aus anderen Objekten (einem Aggregat) bestehen und die alle ihre Teile benötigen, um konsistent zu sein (an aggregate root), dann ist das Repository-Muster die beste Lösung, da es alle Persistenzdetails abstrahiert. Ihre App fordert lediglich ein "Produkt" an und das Repository gibt es als Ganzes zurück, unabhängig davon, wie viele Tabellen oder Abfragen zum Wiederherstellen des Objekts erforderlich sind.

Basierend auf Ihrem Codebeispiel verfügen Sie nicht über "echte" Geschäftsobjekte. Sie haben Datenstrukturen, die von Hibernate verwendet werden. Ein Geschäftsobjekt basiert auf Geschäftskonzepten und Anwendungsfällen. Das Repository ermöglicht es dem BL, sich nicht darum zu kümmern, wie das Objekt beibehalten wird. In gewisser Weise fungiert ein Repository als "Konverter/Mapper" zwischen dem Objekt und dem Modell, das beibehalten wird. Grundsätzlich reduziert das Repo die Objekte auf die für die Persistenz erforderlichen Daten.

Ein Geschäftsobjekt ist keine ORM-Entität . Es ist aus technischer Sicht könnte, sondern aus gestalterischer Sicht pov, man modelliert das Business-Zeug, die anderen Modelle das Persistenz-Zeug. In vielen Fällen sind diese nicht direkt kompatibel.

Der größte Fehler besteht darin, Ihr Geschäftsobjekt entsprechend den Speicheranforderungen und der Denkweise zu gestalten. Und entgegen der Meinung vieler Entwickler besteht ein ORM-Zweck nicht darin, Geschäftsobjekte zu erhalten. Sein Zweck ist es, eine 'oop'-Datenbank über einem rdbms zu simulieren. Die ORM-Zuordnung erfolgt zwischen Ihren DB-Objekten und Tabellen, nicht zwischen App-Objekten (noch weniger bei Geschäftsobjekten) und Tabellen.

88
MikeSW