Prenons un autre exemple moins chargé de conceptions et d’attentes. J'ai un enum ici, et c'est l'ensemble des priorités pour un bogue.
Quelle valeur stockez-vous dans la base de données?
Donc, je pourrais être le stockage 'C'
, 'H'
, 'M'
et 'L'
dans la base de données. Ou 'HIGH'
etc. Cela pose le problème des données fortement typées . Il existe un ensemble connu de valeurs valides, et si vous ne stockez pas cet ensemble dans la base de données, il peut être difficile de travailler avec.
Pourquoi stockez-vous les données dans le code?
Vous avez List<String> priorities = {'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'};
ou quelque chose à cet effet dans le code. Cela signifie que vous disposez de plusieurs mappages de ces données vers le format approprié (vous insérez des majuscules dans la base de données, mais vous les affichez comme Critical
). Votre code est maintenant aussi difficile à localiser. Vous avez lié la représentation de l'idée à la base de données à une chaîne stockée dans le code.
Partout où vous avez besoin d'accéder à cette liste, vous devez avoir une duplication de code ou une classe avec un groupe de constantes. Ni de ce qui sont de bonnes options. Il ne faut pas oublier non plus que d’ autres applications peuvent utiliser ces données (qui peuvent être écrites dans d’autres langages - l’application Web Java utilise un système de génération de rapports Crystal Reports et un travail par lots Perl y introduisant des données). Le moteur de génération de rapports doit connaître la liste de données valides (que se passe-t-il s'il n'y a rien de 'LOW'
prioritaire et que vous devez savoir qu'il s'agit d'une priorité valide pour le rapport?), Et le travail par lots contiendrait les informations valides. les valeurs sont.
De manière hypothétique, vous pourriez dire "nous sommes une boutique mono-langue - tout est écrit en Java" et ne posséder qu'un seul fichier .jar contenant ces informations - mais cela signifie désormais que vos applications sont étroitement liées les unes aux autres et que .jar contient les données. Vous devrez publier la partie création de rapports et la partie mise à jour par lot, ainsi que l'application Web, à chaque modification - et espérez que cette publication se déroule sans problème pour toutes les parties.
Que se passe-t-il lorsque votre patron souhaite une autre priorité?
Votre patron est venu aujourd'hui. Il y a une nouvelle priorité - CEO
. Maintenant, vous devez modifier tout le code , recompiler et redéployer.
Avec une approche 'enum-in-the-table', vous mettez à jour la liste enum afin de définir une nouvelle priorité. Tout le code qui obtient la liste la extrait de la base de données.
Les données sont rarement seules
Avec les priorités, les clés de données dans d' autres tables peuvent contenir des informations sur les flux de travail ou indiquer qui peut définir cette priorité ou non.
Revenons un peu au genre mentionné dans la question: le genre a un lien avec les pronoms utilisés: he/his/him
et she/hers/her
... et vous voulez éviter de le coder en dur dans le code lui-même. Et ensuite, votre patron passe et vous devez ajouter que vous avez le 'OTHER'
genre (pour que ce soit simple) et vous devez associer ce genre à they/their/them
... et votre patron voit ce que Facebook a et ... eh bien, oui.
En vous limitant à un bit de données fortement typé plutôt qu’à une table d’énumération, vous devez maintenant répliquer cette chaîne dans un tas d’autres tables afin de conserver cette relation entre les données et ses autres bits.
Qu'en est-il des autres magasins de données?
Peu importe où vous stockez cela, le même principe existe.
- Vous pourriez avoir un fichier,
priorities.prop
qui a la liste des priorités. Vous lisez cette liste à partir d'un fichier de propriétés.
Vous pouvez avoir une base de données de magasin de documents (telle que CouchDB ) ayant une entrée pour enums
(puis écrire une fonction de validation en JavaScript ):
{
"_id": "c18b0756c3c08d8fceb5bcddd60006f4",
"_rev": "1-c89f76e36b740e9b899a4bffab44e1c2",
"priorities": [ "critical", "high", "medium", "low" ],
"severities": [ "blocker", "bad", "annoying", "cosmetic" ]
}
Vous pourriez avoir un fichier XML avec un peu d'un schéma:
<xs:element name="priority" type="priorityType"/>
<xs:simpleType name="priorityType">
<xs:restriction base="xs:string">
<xs:enumeration value="critical"/>
<xs:enumeration value="high"/>
<xs:enumeration value="medium"/>
<xs:enumeration value="low"/>
</xs:restriction>
</xs:simpleType>
L'idée de base est la même. Le magasin de données lui-même est l'endroit où la liste des valeurs valides doit être stockée et appliquée. En le plaçant ici, il est plus facile de raisonner sur le code et les données. Vous n'avez pas à vous soucier de vérifier de façon défensive ce que vous avez à chaque fois (majuscule ou minuscule? Pourquoi y a-t-il un chritical
type dans cette colonne? Etc ...) parce que vous savez ce que vous récupérez du datastore exactement ce que le magasin de données s'attend à ce que vous l'envoyiez autrement - et vous pouvez lui demander une liste de valeurs valides.
La livraison
L'ensemble des valeurs valides sont des données , pas du code. Vous ne devez lutter pour DRY le code - mais la question de la duplication est que vous dupliquez les données dans le code, plutôt que de respecter sa place en tant que données et le stocker dans une base de données.
Cela facilite l'écriture de plusieurs applications sur le magasin de données et évite d'avoir des instances dans lesquelles vous devrez déployer tout ce qui est étroitement couplé aux données, car vous n'avez pas couplé votre code aux données.
Cela facilite le test des applications, car vous n'avez pas à retester l'intégralité de l'application lorsque la CEO
priorité est ajoutée, car vous ne disposez d'aucun code qui se soucie de la valeur réelle de la priorité.
Le fait de pouvoir raisonner le code et les données indépendamment les uns des autres facilite la recherche et la correction des bogues lors de la maintenance.