Facciamo un altro esempio meno denso di concezioni e aspettative. Ho un enum qui, ed è l'insieme delle priorità per un bug.
Quale valore stai memorizzando nel database?
Quindi, potrei essere la memorizzazione 'C'
, 'H'
, 'M'
, e 'L'
nel database. O 'HIGH'
così via. Questo ha il problema dei dati digitati con stringhe . Esiste un set noto di valori validi e, se non lo memorizzi nel database, può essere difficile lavorarci.
Perché stai memorizzando i dati nel codice?
Hai List<String> priorities = {'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'};
qualcosa o qualcosa del genere nel codice. Significa che hai vari mapping di questi dati nel formato corretto (stai inserendo tutti i tappi nel database, ma li stai visualizzando come Critical
). Il tuo codice ora è anche difficile da localizzare. La rappresentazione del database dell'idea è stata associata a una stringa memorizzata nel codice.
Ovunque sia necessario accedere a questo elenco, è necessario disporre della duplicazione del codice o di una classe con un gruppo di costanti. Nessuna delle due sono buone opzioni. Non bisogna inoltre dimenticare che esistono altre applicazioni che possono utilizzare questi dati (che possono essere scritti in altre lingue: l'applicazione Web Java ha un sistema di reportistica Crystal Reports utilizzato e un processo batch Perl che inserisce i dati in esso). Il motore di report dovrebbe conoscere l'elenco di dati valido (cosa succede se non c'è nulla contrassegnato in 'LOW'
priorità e devi sapere che è una priorità valida per il report?) E il processo batch avrebbe le informazioni su ciò che è valido i valori sono.
Ipoteticamente, potresti dire "siamo un negozio in una sola lingua - tutto è scritto in Java" e abbiamo un singolo .jar che contiene queste informazioni - ma ora significa che le tue applicazioni sono strettamente collegate tra loro e che .jar contenente i dati. Dovrai rilasciare la parte di reportistica e la parte di aggiornamento batch insieme all'applicazione Web ogni volta che si verifica una modifica e sperare che tale versione si svolga senza problemi per tutte le parti.
Cosa succede quando il tuo capo vuole un'altra priorità?
Il tuo capo è venuto oggi. C'è una nuova priorità - CEO
. Ora devi andare a cambiare tutto il codice e fare una ricompilazione e ridistribuire.
Con un approccio "enum-in-the-table", aggiorni l'elenco enum per avere una nuova priorità. Tutto il codice che ottiene l'elenco lo estrae dal database.
I dati raramente sono soli
Con le priorità, le chiavi dei dati in altre tabelle che potrebbero contenere informazioni sui flussi di lavoro o chi può impostare questa priorità o altro.
Tornando al genere come menzionato nella domanda per un po ': Il genere ha un link ai pronomi in uso: he/his/him
e she/hers/her
... e vuoi evitare di codificarlo nel codice stesso. E poi arriva il tuo capo e devi aggiungere che hai il 'OTHER'
genere (per renderlo semplice) e devi mettere in relazione questo genere con they/their/them
... e il tuo capo vede cosa ha Facebook e ... beh, sì.
Limitando te stesso a un bit di dati tipicamente stringa piuttosto che a una tabella enum, ora hai bisogno di replicare quella stringa in un gruppo di altre tabelle per mantenere questa relazione tra i dati e gli altri bit.
Che dire di altri archivi dati?
Non importa dove lo memorizzi, esiste lo stesso principio.
- Potresti avere un file
priorities.prop
con l'elenco delle priorità. Hai letto questo elenco da un file di proprietà.
Potresti avere un database di archivio documenti (come CouchDB ) che ha una voce per enums
(e quindi scrivere una funzione di validazione in JavaScript ):
{
"_id": "c18b0756c3c08d8fceb5bcddd60006f4",
"_rev": "1-c89f76e36b740e9b899a4bffab44e1c2",
"priorities": [ "critical", "high", "medium", "low" ],
"severities": [ "blocker", "bad", "annoying", "cosmetic" ]
}
Potresti avere un file XML con un po 'di uno schema:
<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'idea di base è la stessa. L'archivio dati stesso è dove è necessario archiviare e applicare l'elenco di valori validi. Inserendolo qui, è più facile ragionare sul codice e sui dati. Non devi preoccuparti di controllare in modo difensivo quello che hai ogni volta (è maiuscolo o inferiore? Perché c'è un chritical
tipo in questa colonna? Ecc ...) perché sai che cosa stai recuperando dal datastore è esattamente ciò che l'archivio dati si aspetta che invii altrimenti - e puoi interrogare l'archivio dati per un elenco di valori validi.
L'asporto
L'insieme di valori validi sono dati , non codice. È Non c'è bisogno di lottare per DRY codice - ma la questione della duplicazione è che si sta duplicando i dati nel codice, piuttosto che rispettando il suo posto come dati e la memorizzazione in un database.
Semplifica la scrittura di più applicazioni sull'archivio dati ed evita di avere istanze in cui è necessario distribuire tutto ciò che è strettamente accoppiato ai dati stessi, poiché non è stato accoppiato il codice ai dati.
Semplifica il test delle applicazioni perché non è necessario ripetere il test dell'intera applicazione quando CEO
viene aggiunta la priorità, poiché non si dispone di alcun codice che si preoccupa del valore effettivo della priorità.
Essere in grado di ragionare sul codice e sui dati indipendentemente l'uno dall'altro semplifica la ricerca e la correzione di bug durante la manutenzione.