Les objets ignorant la persistance sont-ils capables d'implémenter le chargement paresseux?

12

L'ignorance de la persistance est une application du principe de responsabilité unique, ce qui signifie en pratique que les objets de domaine ( DO ) ne doivent pas contenir de code lié à la persistance, ils doivent uniquement contenir une logique de domaine.

a) Je suppose que cela signifie que le code qui contacte les couches inférieures (c'est-à-dire les couches de persistance) vit en dehors du modèle de domaine dans d'autres classes ( OC ) d'une couche de logique métier?

b) Si mon hypothèse sous a) est correcte, alors DO , disons Customer, ne contient jamais de méthodes telles que GetCustomersou GetCustomerByID?

c) Si mes hypothèses sous a) et b) sont correctes, et en supposant que l' Customerobjet de domaine utilise le chargement paresseux pour certaines de ses propriétés, alors à un moment donné Customer, la logique interne doit contacter OC , qui à son tour récupère les données différées. Mais si vous devez Customercontacter OC pour recevoir des données différées, alors nous ne pouvons pas vraiment affirmer que les objets de domaine ne contiennent pas de logique liée à la persistance?!

Je vous remercie

RÉPONDRE À jkohlhepp

1) Je suppose OrderProviderque les CustomerProviderclasses sont contenues dans la couche logique métier?

2) Je comprends de votre réponse que mes hypothèses sous b) sont correctes?

3)

... Je vérifierais si un champ de commandes privées a été rempli ou s'il était nul. S'il est nul ...

Mais pour autant que je sache, dès que le code de domaine doit vérifier si le orderchamp privé a été rempli, et si ce n'est pas le cas, en contactant OrderProvider, nous violons déjà le principe PI ?!

user1483278
la source

Réponses:

4

Je crois que vous avez raison dans vos hypothèses A et B concernant l'ignorance de la persistance.

La meilleure façon d'accomplir un chargement paresseux d'objets de base de données dépend largement de votre problème et de votre implémentation. Cependant, je vais essayer une réponse générique sur la façon de faire un chargement paresseux tout en maintenant la séparation des préoccupations entre la persistance et les classes logiques de domaine.

J'ai tendance à implémenter l'ignorance de la persistance en utilisant les classes suivantes:

  • Classes de domaine - par exemple Client
  • Classes de fournisseur / référentiel - par exemple, CustomerProvider
  • Classes d'interrogation de base de données génériques - par exemple DatabaseQuery

La classe DatabaseQuery serait responsable de l'utilisation du pilote de base de données pour interroger la base de données et assembler les données résultantes dans un jeu de résultats générique tel qu'un DataTable. Le CustomerProvider serait responsable de l'utilisation de la classe DatabaseQuery pour exécuter SQL sur la base de données et utiliser les résultats de ce SQL pour assembler les instances du client. Le client serait un objet de domaine «pur» contenant des données et une logique liées aux clients.

Quant à savoir si les classes de fournisseurs doivent être dans le niveau métier ou le niveau données, je n'ai pas d'opinion bien arrêtée. Je peux voir un cas pour les deux. La partie importante est que vous séparez les responsabilités entre les classes.

Voyons maintenant le chargement paresseux. Disons que je voulais que le client ait une collection de commandes, mais je ne veux pas retirer les commandes de la base de données à moins que le consommateur ne tente d'y accéder. Je créerais une propriété sur le client appelée Commandes. Dans le getter de cette propriété, je vérifierais si un champ de commandes privées était rempli ou s'il était nul. S'il est nul, chargez les commandes à partir de la base de données à l'aide d'un OrderProvider. Sinon, renvoyez simplement la collection qui était déjà chargée.

À mon avis, la nécessité pour le client de contacter OrderProvider ne viole pas PI. Le client ne sait toujours pas comment il reçoit les commandes. Il sait juste qu'il les obtient de OrderProvider. Il peut y avoir d'autres raisons de dissocier le client de OrderProvider, mais je ne pense pas que PI soit un problème ici.

Cela suppose que vous effectuez manuellement l'ignorance de la persistance. Si vous utilisez un cadre ORM tel que Entity Framework ou Hibernate, ces cadres ont généralement des fonctionnalités pour prendre en charge le chargement différé de manière automatique.

RationalGeek
la source
salut, au cas où vous trouveriez le temps - j'ai édité mon message en réponse à votre réponse
user1483278
1
@ user1483278 J'ai modifié ma réponse pour, espérons-le, répondre à ces questions.
RationalGeek
Que signifie PI?
Kugel
Ignorance de la persistance
RationalGeek
2

Vous avez juste une classe de câblage qui remplit les objets du domaine (par exemple, quelque chose appelé "référentiel"). Vous pouvez implémenter le chargement paresseux ou tout type de schéma de cohérence de cache que vous souhaitez et les objets de domaine ne sont pas plus sages. Vous séparez la responsabilité de remplir les objets de domaine des objets de domaine.

Erik Dietrich
la source