Gestione dei valori "non specificati" nel software

2

Quindi sto lavorando a un prodotto software in cui abbiamo un numero di campi che il cliente può lasciare vuoto, alcuni dei quali sono numerici. Per persistere nel database utilizziamo colonne nullable. Facile pisello.

Sto considerando l'utilità di un modello di dominio orientato agli oggetti e una cosa che mi infastidisce è il problema dei campi nullable.

La ragione è che nel mondo di Java e C # si trova spesso il consiglio di non avere valori nulli e, in effetti, scrivere codice con controlli nulli su tutto il posto fa schifo. E quindi si ottengono eccezioni di riferimento null quando si dimentica di verificare la presenza di null. Ed è un casino. Quindi un approccio "buono" è quello di inizializzare tutto quando lo si dichiara.

Ora, l'idea di null ha effettivamente senso per questi campi ... il cliente non ha inserito un valore quindi ha valore "no" (non 0, non -1, ecc.). Ma i programmatori di applicazioni e i linguaggi di programmazione sembrano essere configurati per la logica binaria piuttosto che per quella ternaria, e anche per le variabili si meritano di avere un valore piuttosto che avere un valore ma forse anche no.

Con il design orientato agli oggetti presumo che si possa inventare un sistema intelligente di rappresentare casi in cui non c'è valore "no" ma personalmente non ho ancora fatto l'analisi e il motivo è che trovo che il cambiamento incrementale vende di più alla gente di quanto non facciano i cambiamenti radicali, quindi proporre un modello di dominio orientato agli oggetti che sia "troppo orientato agli oggetti" potrebbe uccidere l'idea e quindi le mie speranze di migliorare la struttura del nostro software. Preferirei proporre un modello di dominio "versione 0" che funzioni ed è facile da vendere internamente ... e quindi tutto ciò che riguarda i valori nulli ha un peso nella mia mente.

Dato che stiamo usando C #, potrei semplicemente definire numeri nullable, ma è molto semplice aggiungere un punto interrogativo. Ma non sono convinto che solo perché è possibile è anche l'approccio migliore.

Quindi, con tutta questa spazzatura di fondo la mia domanda è la seguente: in che modo la vostra azienda ha gestito valori "inesistenti" in un modello di dominio orientato agli oggetti, in che modo l'avete trovato efficace e in che modo avete trovarlo inefficace?

I miei criteri di selezione per la "risposta" saranno quelli che sembrano più "vendibili" come definiti nella spazzatura di sfondo. Ma davvero mi piacerebbe vedere che cosa le persone escano e imparare alcune cose nuove così ogni risposta con qualche pensiero dietro di essa riceverà un upvote da me.

Nota: ho visto altre discussioni sui valori nulli in altri thread ma nulla che si allinea abbastanza con ciò di cui voglio parlare, quindi una nuova domanda.

MODIFICA: l'ambito della mia domanda include proprietà tipizzate come i numeri. Quindi in C # un modo per consentire la rappresentazione di un prezzo di acquisto nullo sarebbe dichiarare "PurchasePrice" come "decimale?" che è il tipo decimale annullabile. Vedo solo una serie di svantaggi ai numeri (ad esempio) che possono anche essere nulli, quindi sto cercando un'alternativa.

EDIT 2: Il pattern Null Object ha senso per i riferimenti e l'uso di un tipo nullable per i valori appare come se fosse trattabile con coalescenza. Ciò che mi infastidisce nel coalescing di tipi nulli è "cosa succede se qualcuno dimentica di coalizzarsi e siamo esposti a un'eccezione di riferimento null?" ... e suppongo che potrei forse usare uno strumento di analisi statica che assicura che la coalescenza sia usata dove ci si aspetta che placare questa preoccupazione.

EDIT 2 ': In un certo senso, se qualcuno ha preso una decisione consapevole di rendere nullable un campo, aggiunge la capacità di rappresentare un'informazione aggiuntiva che altrimenti avrebbe bisogno di un altro campo per rappresentarla come un valore booleano HasValue. Ciò significa che gli zeloti "anti-null" che ho incontrato in passato erano forse errati, e l'uso misurato della nullità può di fatto migliorare un design?

    
posta Paul 30.01.2014 - 17:36
fonte

2 risposte

2

Penso che stai scambiando qualcosa qui. Il problema di null in lingue come Java e C # è che i tipi di riferimento sono null per impostazione predefinita. Ad esempio, null è implicito. Ciò significa che non c'è modo di esprimere l'idea del tipo di riferimento che ha sempre un valore valido. Devi sempre controllare null . Anche se sei sicuro che il valore non può essere null , la legge di Murphy dice che succederà qualche volta, quindi è necessario un controllo. Non c'è modo di fare compilare il controllo da parte del compilatore. Naturalmente ci sono modi come i contratti di codice, ma quelli sono relativamente nuovi in quelle lingue e richiedono un lavoro aggiuntivo da parte dello sviluppatore per fare bene.

Il modo in cui i tipi di valore Nullable funzionano è esattamente come dovrebbe funzionare. Il compilatore sa che c'è uno stato aggiuntivo e sa come si lavora con la variabile. Quindi può creare un errore quando vede che esiste la possibilità di dereferenziare questo stato di null . Ad esempio, non puoi aggiungere Nullable<int> e int semplicemente perché il compilatore sa che esiste la possibilità che il primo valore sia null . Quindi ti costringe a fare il controllo in anticipo. Anche il semplice assegnamento dal tipo nullable al non nullable è controllato dal compilatore semplicemente grazie al suo tipo. Nessuna cosa è possibile per i tipi di riferimento. Ovviamente c'è il problema del programmatore che aggiunge appena .Value ad ogni accesso e si fa con esso, ma questo è un problema di disciplina del programmatore che nessuno strumento può risolvere.

Riassunto. Le tue preoccupazioni sui tipi di valori nullable sono completamente ingiustificate perché null è solo un problema quando è implicito e il compilatore non può controllare eventuali errori di accesso al valore nullo. Quale non è il caso dei tipi di valore Nullable .

    
risposta data 30.01.2014 - 19:32
fonte
-1

C'è uno schema chiamato NullObject .

L'unica ragione per cui direi che questo può vendere è che i tuoi test se questo oggetto è NUll o no sono nell'oggetto NUll e quindi ... Quando il tuo software cresce, c'è esattamente un posto dove cercare il comportamento del valore NULL. La duplicazione del codice viene rimossa supponiamo:

function1(x) {
    if x is NULL {
        handleit(x)
    }
}

function2(x) {
    if x is NULL {
        handleit(x)
    }
}

Le due funzioni si trovano in una posizione o classe diversa in modo che handleit(x) non possa essere riutilizzato (dimenticato / typechecks) se non si trova nell'oggetto Null.

Ci sono altre persone che ragionano sulla qualità del software e sul perché è buono. Siate consapevoli che la vostra decisione di progettazione riguarda i vostri sviluppatori ora e i futuri sviluppatori.

Ho usato questo modello una volta e ha funzionato abbastanza bene. Penso che se rispondi alla seguente domanda con sì, l'oggetto Null non è troppo lontano dalla tua scelta:

Should the code that affects the object be in the object?

Modifica1: tipi di valori

Vedendo il link puoi creare i propri tipi di valore. Quindi puoi creare oggetti null di tipo proprio valore. I tipi di valore sono un'ottimizzazione del linguaggio di programmazione. Per i pezzi di codice in cui è necessaria l'ottimizzazione è possibile utilizzarli. E altrimenti usa i tipi di riferimento.

    
risposta data 30.01.2014 - 17:57
fonte

Leggi altre domande sui tag