L'ID métier bien connu d'une entité doit-il être représenté par un type dédié dans DDD / OOP?

9

En termes pratiques, cela signifie utiliser un personnalisé (immuable) classsur un stringou un autre type primitif.

Exemples:

  1. Édition: International Standard Book Number.
  2. Finance: Numéro international d'identification des titres.

Avantages:

  1. Peut assurer le format d'un identifiant.
  2. Devient un membre de première classe du modèle.

Désavantages:

  1. Ajoute une friction de persistance (par exemple Entity Framework).
  2. Plus de code.
Tanière
la source
Devriez-vous utiliser une classe personnalisée? Sûr. Devriez-vous les utiliser comme identifiants? Absolument pas :) Une pièce d'identité avec une signification commerciale causerait des problèmes en cours de route.
Songo
2
@Songo Pour moi, c'est un argument selon lequel les ID devraient avoir une sémantique de valeur , mais les types primitifs ne sont pas les seuls types avec une sémantique de valeur, ce qui n'exclut pas nécessairement les classes imo. N'hésitez pas à poster une réponse concurrente car j'ai oublié de le souligner.
Ixrec
1
Une vieille question à moi a touché le sujet avec différentes opinions: programmers.stackexchange.com/questions/281827/… Je suis allé avec la création des types et continue à le faire.
Ziv

Réponses:

6

Si vous pouvez donner à la classe suffisamment de fonctionnalités utiles pour justifier la complexité supplémentaire de ne pas être une chaîne, faites-le. Pour les identifiants comme ISBN et ISIN, je soupçonne que ce n'est pas le cas.

Pour qu'une classe d'identifiant soit utile, je m'attendrais à ce qu'elle ressemble à ceci:

class ISIN {
    fromCUSIP()
    fromRawISINString()
    toString(ISIN::FormatType)
    getExchange()
    getCountryCode()
    getLastFourDigits()
    getWhateverCode()
    ...
}

Si à la place, cela ressemble plus à ceci:

class ISIN {
    getString()
    setString()
}

Ensuite, j'abandonnerais complètement la classe, j'utiliserais des chaînes régulières partout et je m'assurerais d'utiliser systématiquement "isin" dans tous les noms de variables pertinents.

Notez que dans certaines langues, l'ajout d'un nouveau type n'a presque pas de «complexité ajoutée» dans les programmes typiques, auquel cas vous seriez encouragé à créer le nouveau type même s'il n'avait aucune fonctionnalité. Mais ce n'est pas le cas pour la plupart des langages OOP traditionnels comme C ++.

Ixrec
la source
6

Je dirais oui pour ça. Je dirais que les avantages l'emportent sur les inconvénients dans ce cas. Le code supplémentaire est susceptible d'être assez minimal et le problème de persistance peut être résolu assez facilement en fournissant une sorte de convertisseur entre votre nouvelle classe et le type auquel la base de données s'attend (je n'ai jamais utilisé Entity Framework mais je sais que cela est relativement indolore dans Hiberner).

L'un des avantages que vous pouvez obtenir en définissant votre propre classe est que le compilateur peut garantir que toutes les méthodes qui veulent un ISBN ou un ISIN sauront au moment de la compilation si vous essayez de transmettre la mauvaise valeur. Il sera également beaucoup plus difficile de remplacer accidentellement ce champ dans votre entité. Nous pouvons éviter complètement les erreurs courantes comme celle-ci:

book.setAuthor(otherBook.getAuthorName());
book.setIsbn(otherBook.getAuthorName());
book.setPrice(otherBook.getPrice())

Si ISBN est une classe plutôt qu'un type primitif, le code ci-dessus ne sera même pas compilé, ce qui vous fera gagner beaucoup de temps de débogage plus tard.

Matt Watson
la source
1
setters et getters? Est-ce 1992?
Miles Rout