Infrangeresti il principio DRY mettendo quella logica di validazione ovunque venga usato un codice postale.
D'altra parte, quando si ha a che fare con molti paesi diversi e con i loro diversi sistemi di codici postali, ciò significa che non è possibile convalidare un codice postale se non si conosce il paese in questione. Quindi la tua ZipCode
classe deve anche memorizzare il paese.
Ma poi memorizzi separatamente il Paese sia come parte del Address
(di cui fa parte anche il codice postale), sia come parte del codice postale (per la convalida)?
- Se lo fai, stai violando anche DRY. Anche se non la definisci una violazione DRY (perché ogni istanza ha uno scopo diverso), occupa comunque inutilmente memoria aggiuntiva, oltre ad aprire la porta ai bug quando i valori dei due paesi sono diversi (che logicamente non dovrebbero mai essere).
- Oppure, in alternativa, ti porta alla necessità di sincronizzare i due punti dati per assicurarti che siano sempre gli stessi, il che suggerisce che dovresti davvero archiviare questi dati in un unico punto, vanificando così lo scopo.
- Se non lo fai, allora non è una
ZipCode
classe ma una Address
classe, che conterrà di nuovo un string ZipCode
che significa che siamo tornati al punto di partenza.
Ad esempio, posso parlare con un analista aziendale di un codice postale anziché di una stringa che contiene un codice postale.
Il vantaggio è che puoi parlarne quando descrivi il modello di dominio.
Non capisco la tua affermazione di fondo secondo cui quando un'informazione ha un determinato tipo di variabile, sei in qualche modo obbligato a menzionare quel tipo ogni volta che parli con un analista aziendale.
Perché? Perché non riesci a parlare semplicemente del "codice postale" e ometti completamente il tipo specifico? Che tipo di discussioni stai avendo con il tuo analista aziendale (non tecnico!) In cui il tipo di proprietà è essenziale per la conversazione?
Da dove vengo io, i codici postali sono sempre numerici. Quindi abbiamo una scelta, potremmo memorizzarlo come int
o come string
. Tendiamo a usare una stringa perché non ci si può aspettare operazioni matematiche sui dati, ma mai un analista aziendale mi ha detto che doveva essere una stringa. Tale decisione è lasciata allo sviluppatore (o probabilmente all'analista tecnico, anche se nella mia esperienza non si occupano direttamente del grintoso spirito).
Un analista aziendale non si preoccupa del tipo di dati, purché l'applicazione faccia quello che dovrebbe fare.
La convalida è una bestia difficile da affrontare, perché si basa su ciò che gli umani si aspettano.
Per uno, non sono d'accordo con l'argomento di validazione come un modo per mostrare perché l'ossessione primitiva dovrebbe essere evitata, perché non sono d'accordo che i dati (come verità universale) debbano sempre essere validati in ogni momento.
Ad esempio, cosa succede se si tratta di una ricerca più complicata? Invece di un semplice controllo del formato, cosa succede se la convalida comporta il contatto con un'API esterna e l'attesa di una risposta? Vuoi davvero forzare la tua applicazione a chiamare questa API esterna per ogni ZipCode
oggetto che crei un'istanza?
Forse è un requisito aziendale rigoroso, e quindi è ovviamente giustificabile. Ma questa non è una verità universale. Ci saranno molti casi d'uso in cui questo è più un peso che una soluzione.
Come secondo esempio, quando inserisci il tuo indirizzo in un modulo, è comune inserire il tuo codice postale prima del tuo paese. Sebbene sia bello avere un feedback di convalida immediato nell'interfaccia utente, in realtà sarebbe un ostacolo per me (come utente) se l'applicazione mi avvisasse di un formato zipcode "errato", perché la vera fonte del problema è (ad esempio) che il mio paese non è il paese selezionato per impostazione predefinita, quindi la convalida è avvenuta per il paese sbagliato.
È un messaggio di errore sbagliato, che distrae l'utente e causa inutili confusioni.
Proprio come la validazione perpetua non è una verità universale, né i miei esempi. È contestuale . Alcuni domini dell'applicazione richiedono la convalida dei dati sopra ogni altra cosa. Altri domini non inseriscono la convalida così in alto nell'elenco delle priorità perché la seccatura che ne deriva è in conflitto con le loro priorità effettive (ad esempio l'esperienza dell'utente o la capacità di archiviare inizialmente i dati difettosi in modo che possano essere corretti invece di non permettere mai che siano immagazzinato)
Data di nascita: controlla che sia maggiore della mentalità e inferiore alla data di oggi.
Stipendio: verifica che maggiore o uguale a zero.
Il problema con queste convalide è che sono incomplete, ridondanti o indicative di un problema molto più grande .
Controllare che una data sia maggiore della mentalità è ridondante. La mentalità significa letteralmente che è la data più piccola possibile. Inoltre, dove disegni la linea di pertinenza? Qual è il punto di prevenire DateTime.MinDate
ma permettere DateTime.MinDate.AddSeconds(1)
? Stai criptando un valore particolare che non è particolarmente sbagliato rispetto a molti altri valori.
Il mio compleanno è il 2 gennaio 1978 (non lo è, ma supponiamo che lo sia). Ma supponiamo che i dati nella tua applicazione siano sbagliati e invece dice che il mio compleanno è:
- 1 gennaio 1978
- 1 gennaio 1722
- 1 gennaio 2355
Tutte queste date sono sbagliate. Nessuno di loro è "più giusto" dell'altro. Ma la tua regola di validazione catturerebbe solo uno di questi tre esempi.
Hai anche completamente omesso il contesto di come stai usando questi dati. Se questo viene utilizzato, ad esempio, in un bot di promemoria di compleanno, direi che la convalida è inutile poiché non vi sono conseguenze particolarmente negative per la compilazione della data sbagliata.
D'altra parte, se si tratta di dati governativi e hai bisogno della data di nascita per autenticare l'identità di qualcuno (e la mancata osservanza porta a conseguenze negative, ad esempio negare a qualcuno la sicurezza sociale), allora la correttezza dei dati è fondamentale e devi essere pienamente convalidare i dati. La validazione proposta che hai ora non è adeguata.
Per uno stipendio, c'è un po 'di buon senso in quanto non può essere negativo. Ma se realisticamente ti aspetti che vengano immessi dati senza senso, ti suggerirei di indagare sulla fonte di questi dati senza senso. Perché se non ci si può fidare di inserire dati sensibili, non ci si può fidare di loro per inserire dati corretti .
Se invece lo stipendio viene calcolato dalla tua applicazione e in qualche modo è possibile finire con un numero negativo (e corretto)), un approccio migliore sarebbe quello Math.Max(myValue, 0)
di trasformare i numeri negativi in 0, anziché fallire la convalida. Perché se la tua logica ha deciso che il risultato è un numero negativo, fallire la convalida significa che dovrà ripetere il calcolo, e non c'è motivo di pensare che verrà fuori con un numero diverso la seconda volta.
E se viene fornito un numero diverso, ciò porta di nuovo a sospettare che il calcolo non sia coerente e quindi non ci si possa fidare.
Questo non vuol dire che la validazione non sia utile. Ma la convalida inutile è negativa, sia perché richiede uno sforzo che non risolve davvero un problema, sia per dare alle persone un falso senso di sicurezza.