Voici un petit problème
Avoir une entité, avec un objet valeur. Pas de problème. Je remplace un objet valeur par un nouveau, puis nhibernate insère la nouvelle valeur et rend orphelin l'ancienne, puis la supprime. D'accord, c'est un problème.
L'assuré est mon entité dans mon domaine. Il possède une collection d'adresses (objets de valeur). L'une des adresses est MailingAddress. Lorsque nous voulons mettre à jour l'adresse postale, disons que le code postal était incorrect, conformément à la doctrine de M. Evans, nous devons remplacer l'ancien objet par un nouveau car il est immuable (un objet de valeur, n'est-ce pas?).
Mais nous ne voulons pas supprimer la ligne, car le PK de cette adresse est un FK dans une table MailingHistory. Donc, suivant la doctrine de M. Evans, nous sommes à peu près foutus ici. À moins que je ne crée mes adresses, je n'ai donc pas besoin de le "remplacer" et de simplement mettre à jour son code postal, comme au bon vieux temps.
Que me suggéreriez-vous dans ce cas? À mon avis, les ValueObjects ne sont utiles que lorsque vous souhaitez encapsuler un groupe de colonnes de table de base de données (composant dans nhibernate). Tout ce qui a un identifiant de persistance dans la base de données, il vaut mieux en faire une entité (pas nécessairement une racine agrégée) afin que vous puissiez mettre à jour ses membres sans recréer le graphique d'objet entier, surtout s'il s'agit d'un objet profondément imbriqué.
Êtes-vous d'accord? Est-il permis à M. Evans d'avoir un objet de valeur mutable? Ou un objet de valeur mutable est-il candidat à une entité?
Merci
la source
Réponses:
Tout ce qui a une identité doit être une entité, et tout ce qui n'a pas d'identité est une simple valeur, donc un objet de valeur.
Pour citer Martin Fowler (qui à son tour qoutes Eric Evans)
Raison de faire de votre adresse un objet de valeur:
Si votre adresse est modifiable, vous finirez probablement par visser votre historique de diffusion. Par exemple, si vous expédiez des articles à un client, vous ne pouvez pas être sûr de l'adresse à laquelle vous avez réellement expédié quelque chose par le passé si l'adresse à laquelle votre table MailingHistory fait référence a été modifiée.
L'entrée MailingHistory Nous avons expédié A764 à l'adresse 657 pourrait signifier Nous avons expédié l'article A764 à Boston hier et Nous avons expédié l'article A764 à New York demain.
Si l'adresse postale doit être modifiée, il n'est pas nécessaire de supprimer l'ancienne. Gardez-le et marquez-le comme inactif , et le nouveau comme actif .
Bien sûr, vous pouvez traiter votre adresse comme une entité, mais uniquement lors de la mise à jour, cela ne changera pas le lieu réel auquel l'adresse fait référence, permettant ainsi uniquement la correction des fautes de frappe.
Si vous êtes sûr de pouvoir le garantir, il serait possible d'utiliser une entité.
Mais la meilleure solution à mon humble avis est de ne pas référencer une entité d'adresse dans votre historique de diffusion, mais plutôt d'enregistrer l'adresse spécifique directement dans votre table d'historique de diffusion (en copiant essentiellement les données de l'adresse).
De cette façon, vous savez toujours où vous avez expédié vos articles (ou tout ce que vous envoyez), et puisque vous utiliseriez une entité mutable, votre table d'adresses ne sera pas encombrée.
J'ai travaillé avec / sur plusieurs systèmes ERP, et presque tous ont utilisé cette approche.
Vous aurez une certaine redondance dans votre base de données, mais c'est la manière la plus pragmatique à mon humble avis.
la source
ALTER
soit nécessaire d'utiliser des entités dans des tables distinctes. Cela, à son tour, nécessite des stratégies telles que «toujours joindre la dernière adresse / téléphone / e-mail» dans vosSELECT
requêtes, qui sont difficiles à maintenir maintenables et efficaces. Restez simple, si possible.active
-flag. Bien sûr, vous devez vous assurer de toujours utiliserand active = true
dans vos jointures, de maintenir le drapeau à jour et d'ajouter une contrefaçon à votre table afin que, par exemple, un seul e-mail pour chaque client puisse avoir ce drapeau défini sur true.active=true
. Ce n'est pas ce que j'appellerais simple, c'est exactement pourquoi j'aime votre solution.Je vois 2 choses:
Est-il acceptable que le changement de code postal affecte un enregistrement d'historique? Je pense qu'il serait logique que l'enregistrement historique pointe vers l'ancienne adresse inchangée, vous savez donc que vous l'envoyez à une mauvaise adresse.
Au moment où MailingHistory a FK sur l'adresse, l'adresse a cessé d'être un objet de valeur et est devenue une entité. Les objets de valeur n'ont pas d'identité, ce qui permet à d'autres entités de référencer cette identité. Vous pouvez avoir des adresses dans une table unique avec d'autres tables pointant dessus, mais le seul effet est d'économiser de l'espace. Du point de vue du domaine, si deux entités ont en référence le même type d'objet de valeur, elles ne partagent aucun type d'informations.
la source
IMO l'objet adresse est une entité de votre domaine. Il est partagé par plusieurs entités, possède sa propre identité et est unique à travers le système.
Evans dit:
la source