Modèle de référentiel-Comment le comprendre et comment fonctionne-t-il avec des entités "complexes"?


J'ai du mal à comprendre le modèle de référentiel.

Il y a beaucoup d'opinions sur ce sujet comme dans Modèle de référentiel bien faitmais aussi d'autres choses comme Le référentiel est le nouveau Singletonou encore comme dans Ne pas utiliser DAO utiliser le référentielou simplement prendre Spring JPA Data + Hibernate + MySQL + MAVEN où en quelque sorte un Référentiel semble être le même

Je commence à en avoir assez de lire ce genre de choses puisque à mon humble avis, cela ne peut pas être une chose aussi difficile car elle est affichée dans de nombreux articles.

Je le vois comme ceci: Il semble que ce que je veux est quelque chose comme ceci:

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

Le Service Layerprend *DTO des objets et les transmet au Repository Layerqui n'est fondamentalement rien de plus que "le gars" qui sait comment une entité peut être stockée.

Par exemple, supposons que vous ayez une composition de certains outils (veuillez noter que c'est juste un 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;
}

La chose que je n'obtiens pas est la partie où je reçois un ToolSetDTO objet du client.

Comme je l'ai compris jusqu'à présent, je pourrais écrire un ToolSetRepository, avec une méthode ToolSetRepository.save(ToolSetDTO toolSetDto), que "sait comment stocker" un ToolSetDTO. Mais presque tous les tutoriels ne passent pas le *DTO mais le Entity à la place.

Ce qui me dérange ici, c'est que si vous prenez monToolSet exemple d'en haut, je devrais faire les étapes suivantes:

  1. Prenez toolSetDto et vérifiez si non null
  2. Pour chaque tool*Dto appartenant à toolSetDto
    a) Si a un id valide, alors convertissez de DTO en Entity sinon créez une nouvelle entrée de base de données
    b) toolDescriptionDto et convertissez-la/enregistrez-la dans la base de données ou créez une nouvelle entrée
  3. Après avoir vérifié ceux ci-dessus instanciate ToolSet (entité) et le configurer pour le persister dans la base de données

Tout cela est trop complexe pour laisser simplement la fonction de service (interface pour le client) gérer cela.

Ce que je pensais about créait par exemple un ToolSetRepository mais la question ici est

  • Prend-il un objet entité ToolSet ou utilise-t-il un objet DTO?
  • Dans tous les cas: le *Repository est-il autorisé à utiliser d'autres objets de référentiel? Comme lorsque je veux enregistrer ToolSet, mais j'ai pour stocker Tool et ToolDescription abord - puis-je utiliser ToolRepository et ToolDescriptionRepository dans ToolSetRepository?
    Si oui: Pourquoi ne casse-t-il pas le modèle de référentiel? Si ce modèle est essentiellement une couche entre le service et mon framework ORM il ne "se sent pas bien" d'ajouter des dépendances à d'autres classes *Repository pour des raisons de dépendance.

Je ne sais pas pourquoi je n'arrive pas à comprendre ça. Cela ne semble pas que compliqué mais il y a toujours de l'aide comme Spring Data. Une autre chose qui me dérange car je ne vois vraiment pas comment cela rend quelque chose plus facile. Surtout que j'utilise déjà Hibernate-je ne vois pas l'avantage (mais c'est peut-être une autre question).

Donc .. Je sais c'est une longue question mais j'y ai déjà mis quelques jours de recherche. Il y a déjà du code existant sur lequel je travaille en ce moment qui commence à devenir un gâchis parce que je ne peux tout simplement pas voir à travers ce modèle.

J'espère que quelqu'un peut me donner une image plus grande que la plupart des articles et tutoriels qui ne vont pas au-delà de la mise en œuvre d'un exemple très, très simple d'un modèle de référentiel.

Author: Stefan Falk, 2015-07-08

1 answers

, Vous pouvez lire mon référentiel "pour les nuls" post - pour comprendre la simple principe de du référentiel. Je pense que votre problème est que vous travaillez avec des DTO et dans ce scénario, vous n'utilisez pas vraiment le modèle de référentiel, vous utilisez un DAO.

La principale différence entre un référentiel et un dao est qu'un référentiel ne renvoie que des objets compris par la couche appelante. La plupart du temps, le référentiel est utilisé par la couche métier et retourne business objects. Un dao renvoie des données qui peuvent ou non être un objet métier entier, c'est-à-dire que les données ne sont pas un concept métier valide.

Si vos objets métier ne sont que des structures de données, cela peut indiquer que vous avez un problème de modélisation, c'est-à-dire une mauvaise conception. Un référentiel a plus de sens avec des objets "riches" ou au moins correctement encapsulés. Si vous ne faites que charger/enregistrer des structures de données, vous n'avez probablement pas besoin d'un référentiel, l'orm est suffisant.

Si vous avez affaire à des affaires les objets qui sont composés à partir d'autres objets (un agrégat) et cet objet a besoin de toutes ses parties pour être cohérent (une racine d'agrégat) alors le modèle de référentiel est la meilleure solution car il va abstraire tous les détails de persistance. Votre application demandera simplement un "produit" et le référentiel le renverra dans son ensemble, quel que soit le nombre de tables ou de requêtes nécessaires pour restaurer l'objet.

Sur la base de votre exemple de code, vous n'avez pas de "vrais" objets métier. Vous avoir des structures de données utilisées par Hibernate. Un objet métier est conçu en fonction de concepts métier et de cas d'utilisation. Le référentiel permet au BL de ne pas se soucier de la persistance de cet objet. D'une certaine manière, un référentiel agit comme un "convertisseur/mappeur" entre l'objet et le modèle qui sera persisté. Fondamentalement, le dépôt "réduit" les objets à la valeur requise pour les données de persistance.

Un objet métier n'est pas {[4] } un ORM entity.It pourrait{[22] } être d'un point technique de vue , mais à partir d'un point de vue de conception, on modélise les affaires les autres modèles de persistance. Dans de nombreux cas, ceux-ci ne sont pas directement compatibles.

La plus grande erreur est de concevoir votre objet métier en fonction des besoins de stockage et de l'état d'esprit. Et contrairement à ce que de nombreux développeurs croient, un but ORM n'est pas de persister business objects. Son but est de simuler une base de données 'oop' au-dessus d'un SGBDR. Le mappage ORM est entre vos objets db et vos tables, pas entre les objets app (encore moins lorsque traiter avec des objets métier) et des tables.

 115
Author: MikeSW, 2015-08-03 16:23:21