Objets immuables et DDD vont-ils de pair?

18

Considérons un système qui utilise DDD (ainsi: tout système qui utilise un ORM). Le point de tout système réaliste, dans presque tous les cas d'utilisation, sera de manipuler ces objets de domaine. Sinon, il n'y a ni effet ni but réels.

La modification d'un objet immuable entraînera la génération d'un nouvel enregistrement après la persistance de l'objet, ce qui crée un gonflement massif dans la source de données (sauf si vous supprimez les enregistrements précédents après les modifications).

Je peux voir l'avantage d'utiliser des objets immuables, mais dans ce sens, je ne vois jamais de cas utile pour utiliser des objets immuables. Est-ce mal?

Steven Evers
la source

Réponses:

16

Le calcul à l'aide d'objets immuables (comme dans la programmation fonctionnelle) n'implique pas nécessairement la persistance de chaque objet généré!

Steven A. Lowe
la source
Je ne vois pas d'exemple où ce scénario utilise des objets immuables de toute façon - alors ils seraient là sans but particulier. Ai-je tort?
Steven Evers
1
je pensais que les objets immuables seraient utiles pour les calculs intermédiaires (dans les threads parallèles)
Steven A. Lowe
11

Est-ce que immuable dans le domaine signifie qu'il doit être immuable dans la base de données? Par exemple, considérez ce qui suit en supposant que le client a toujours une adresse:

customer.address = new Address('My Castle', 'Kings street');
customer_repo.save(customer);

maintenant le sql suivant est exécuté en considérant que l'ID client est 1:

INSERT INTO addresses (customer_id, name, street)
VALUES (1, 'My Castle', 'Kings street');

maintenant, le changement suivant est apporté à l'adresse:

customer.address = new Address('Pauper palace', 'Outlands');
customer_repo.save(customer);

et la couche de persistance, étant très intelligent, exécute le sql suivant:

UPDATE addresses SET name='Pauper palance', street='Outlands'
WHERE customer_id = 1;

De cette façon, vous évitez la surcharge d'une instruction DELETE AND INSERT distincte. Je pense aussi que certains SGBDR ont INSERT REPLACE ou quelque chose. MySql a REMPLACER .

andho
la source
+1 Je suis d'accord avec vous sur le principe général: je ne vois pas pourquoi les objets de domaine immuables doivent nécessairement signifier des lignes de base de données immuables.
Andres F.
? Dans le cas ci - dessus si jamais nous avions besoin de changer l'attribut ville de la classe d'adresse pour un client donné , comment pourrions - nous gérer, assumer plus , le client peut avoir plusieurs adresses il aa un à plusieurs navires de la relation entre le client et les adresses
Sudarshan
1
@Sudarshan c'est juste un moyen de créer un «objet de valeur immuable», pas vraiment immuable dans la base de données. Pour des raisons de performances. Chaque situation doit être gérée spécifiquement bien sûr. Je préfère le sourçage d'événements pour mon domaine maintenant, mais j'en suis un peu accro.
andho
@Sudarshan pour répondre spécifiquement à votre question, vous venez d'exécuter une requête de mise à jour qui met à jour la ligne à la nouvelle valeur. S'il s'agit d'un à plusieurs, alors les adresses auront une sorte d'identifiant dans la racine d'agrégat client qui sera utilisé pour l'identifier de manière unique dans la base de données. Ensuite, cet identifiant et customer_id seront utilisés pour mettre à jour cette ligne dans la table «adresse».
andho
@andho "c'est juste un moyen de créer un" objet de valeur immuable ", pas vraiment immuable dans la base de données." cela a vraiment fait ma journée merci
Sudarshan
6

Dans DDD, les objets immuables sont à peu près équivalents aux objets de valeur. Ces objets ne sont pas des entités, ils n'ont pas d'identité. Par conséquent, je persiste toujours les objets de valeur en tant que colonnes de l'entité dans laquelle ils sont contenus (avec N / Hibernate, vous pouvez utiliser des composants pour cela). Ils n'ont pas leur propre table.

guillaume31
la source
4

Cela dépend de la façon dont l'objet immuable est mappé dans la base de données. S'il s'agit simplement d'un composant comme un DateTime (de la bibliothèque Joda Time), la modification de la valeur entraînera une mise à jour plutôt qu'une insertion. Cependant, si l'immuable est plus complexe nécessitant une ligne dans un tableau, vous avez le problème de ballonnement.

Je suppose que, même si c'est un argument faible, vous pouvez mettre en œuvre une piste d'audit de cette façon. Chaque modification de l'immuable peut être suivie à travers les inserts. Il existe cependant de bien meilleures façons de procéder.

Dans l'ensemble, avoir des objets de domaine immuables (au lieu de simplement leurs composants) semble un peu en décalage avec la persistance.

Gary Rowe
la source
Pas du tout. Les composants sont très utiles car ils permettent aux objets de domaine d'être composés différemment des mêmes données sous-jacentes. Les problèmes viennent avec l'application de l'immuabilité. Personnellement, je traiterais les objets de domaine comme mutables (à l'exception des champs de clé primaire) et je resterais simple.
Gary Rowe
"Dans l'ensemble, avoir des objets de domaine immuables (au lieu de simplement leurs composants) semble un peu en décalage avec la persistance." À votre avis, où aurions-nous besoin d'avoir des objets de valeur qui ne devraient pas être modélisés en tant que composants (terminologie Hibernate)? --- Désolé d'avoir mal tapé mon dernier commentaire et donc supprimé.
Sudarshan
Évitez les composants lorsqu'une seule entité est entièrement représentée par une ligne et qu'aucune des données n'est partagée par un autre objet de domaine.
Gary Rowe
4

Cela dépend du domaine. DDD ne spécifie pas que le paradigme de programmation est orienté objet. Le paradigme orienté objet est cependant bien adapté à l'application typique qui doit être conservée dans une base de données.

DDD indique simplement que vous devez créer votre logiciel autour d'un modèle de domaine qui représente le problème réel que le logiciel essaie de résoudre. Si ce problème était par exemple mathématique par nature, alors l'implémentation de la couche domaine en utilisant une programmation fonctionnelle et des structures de données immuables aurait beaucoup de sens.

Si d'un autre côté, le problème est davantage lié à une application d'entreprise typique et que vous utilisez des structures d'objets immuables pour tous vos objets de domaine, je dirais que vous ne suivez pas DDD. Je peux proposer au moins deux arguments:

  • Votre implémentation ne représente pas un modèle de domaine de votre domaine problématique. Votre domaine problématique dans ce cas est constitué d'entités ayant un état à modifier. Et ce n'est pas ainsi que vous l'avez mis en œuvre.

  • Vous n'avez pas de langue omniprésente. Le langage et les concepts du modèle de domaine ne suivent pas ce que les experts en domaine utilisent.

Remarque: DDD utilise des objets immuables le cas échéant, ils sont simplement appelés objets de valeur.

Donc, je ne dis pas que vous ne pouvez pas créer une application de base de données en utilisant des structures de données purement fonctionnelles, et je ne dis pas que vous ne devriez pas. Je ne pense pas que vous puissiez l'appeler DDD, selon le type d'application

Pete
la source
Peter, excellente réponse. Pourriez-vous jeter un œil à ma question ici stackoverflow.com/questions/13783666/… et m'aider à comprendre mon problème. Je pense que les objets de valeur immuables sont parfaits pour les logiciels qui ne sont pas liés à l'entreprise. La plupart des objets des applications d'entreprise sont modifiables à mon avis. Imaginez avoir un objet de valeur imbriqué profond immuable ... ContactInfo-> PhysicalLocation-> Adresse et vous voulez mettre à jour le code postal ... la création du graphique d'objet entier me semble antichrist, pas seulement un antipattern. Qu'est-ce que tu penses?
Pepito Fernandez
3

Si vous utilisez un ORM tel que Hibernate / NHibernate, vous pouvez définir votre option de cascade pour supprimer automatiquement les objets orphelins. Si une personne a une adresse d'objet de valeur, lorsque vous modifiez l'adresse, la nouvelle sera enregistrée et l'ancienne supprimée car elle est désormais orpheline.

Mike Rowley
la source
0

Les objets de valeur sont presque toujours immuables dans DDD et le modèle flyweight peut être utilisé pour conserver la duplication de cet objet de valeur dans la mémoire, tout comme .NET le fait avec des chaînes. Le principal compromis est la mémoire d'un côté et l'autre côté est l'efficacité créative. Avec le modèle Flyweight, une comparaison basée sur les valeurs doit être effectuée pour déterminer si un objet de valeur nouveau ou reconstitué se trouve déjà dans le cache Flyweight, mais toute autre comparaison après ce point peut généralement être effectuée en toute sécurité par référence, car une seule instance est appliquée. Dans tous les cas, que la mouche soit utilisée ou non, les objets de valeur sont toujours rendus immuables car ils n'ont qu'une identité intrinsèque et donc changer leur valeur changerait leur identité.

jpierson
la source
-1

Il existe une autre façon d'utiliser des objets immuables ...

Au lieu de stocker des valeurs 5.0, 6.0, 7.0, 8.0 et de copier tout l'enregistrement à chaque fois, vous pouvez à la place stocker quelque chose comme ceci: 5.0, +1.0, +1.0, +1.0, puis créer correctement des dépendances pour reconstruire la séquence 5.0 , 6.0, 7.0, 8.0. De cette façon, les petites modifications ne prennent que peu de mémoire ...

tp1
la source