I condizionali dovrebbero essere incorporati nella funzione la cui esecuzione è contingente?

1

Ho una grande struttura dati che sta per essere persistente nel database. Prima che ciò possa accadere, devo convalidarlo e quindi aggiornare un gruppo di sue proprietà in base a varie condizioni specifiche.

Quale stile è più leggibile, con una serie di istruzioni if / else che determinano quali funzioni verranno eseguite in condizioni specifiche o un semplice elenco di funzioni da eseguire che contengono al loro interno le condizioni in base alle quali devono essere eseguite?

Il primo mi dà indentation inferno e if if annidato, il secondo sembra pulito ma dà l'impressione che l'elenco di funzioni venga sempre eseguito e richiede la visualizzazione di ciascuna funzione per vedere le circostanze in cui ciascuna funzione verrà eseguita.

Esempio di if / else style:

function myFunc(myThing){
    if(myThing.myProp === 'someValue'){
        doStuff();
        if(myThing.myProp2 === 1){
            doAThing();
        } else {
            doADifferentThing();
        }
    } else {
        doOtherStuff();
    }
}

Esempio di condizioni nidificate nelle funzioni:

function myFunc(myThing){
    doStuff(myThing);
    doAThing(myThing);
    doADifferentThing(myThing);
    doOtherStuff(myThing);
}

function doStuff(myThing){
    if(myThing.myProp === 'someValue'){
        //Do stuff
    }
}

function doAThing(myThing){
    if(myThing.myProp === 'someValue' && myThing.myProp2 === 1){
        //Do a thing
    }
}

function doADifferentThing(myThing){
    if(myThing.myProp === 'someValue' && myThing.myProp2 !== 1){
        //Do a different thing
    }
}

function doOtherStuff(myThing){
    if(myThing.myProp !== 'someValue'){
        //Do other stuff
    }
}

Questi esempi non sono perfetti, ma si spera che trasmettano ciò che sto chiedendo.

    
posta Legion 07.02.2017 - 18:03
fonte

3 risposte

6

Il secondo approccio è più leggibile e probabilmente sarà più gestibile a lungo termine.

Il contenuto di myFunc è più comprensibile: osservandolo, posso ottenere rapidamente un'idea di alto livello di ciò che sta accadendo qui, non ho bisogno di iniziare a scavare subito attraverso le condizioni nidificate.

Le altre funzioni sono più semplici e più autonome. Se qualcosa cambia per una condizione, non è necessario districare un pasticcio di codice spaghetti nidificato - vai direttamente nella funzione, cambialo, hai finito! Si presta anche ad avere queste funzioni più piccole da sottrarre ad altri moduli in futuro, se necessario.

L'unico lato negativo che riesco a vedere al secondo approccio è che probabilmente ci saranno più tipi di digitazione, ma penso che il compromesso valga più della pena.

Se sei preoccupato per la seconda opzione

gives the impression that the list of functions always executes and requires viewing each function to see the circumstances

potresti cambiare i nomi da doAThing a checkPropAndDoAThing o doThingIfProperty . Ovviamente, se vuoi farlo, dovresti trovare nomi brevi e concisi per le proprietà nelle funzioni, ad esempio: formatNameIfTooLong . In alternativa, aggiungi una descrizione più dettagliata alla documentazione della funzione in modo che l'IDE possa visualizzare la descrizione con i dettagli della condizione all'interno. Questo funzionerà solo se l'IDE lo supporta, ma è comunque probabilmente una buona idea documentarlo.

    
risposta data 07.02.2017 - 18:13
fonte
2

Come regola generale, vuoi separare la decisione sul fatto di fare qualcosa ("logica decisionale") da quello che fai ("codice azione").

Ciò consente di controllare la logica decisionale separatamente dal codice azione. Ti consente di bloccare il codice di azione, controllare tutta la logica decisionale e cercare sorprese di sequenziamento, senza che ALSO debba prendere in giro abbastanza ambienti per testare simultaneamente il codice azione.

Allo stesso tempo, questo ti consente di generare il codice di azione e di svilupparlo e testarlo contemporaneamente.

Sì, nel tuo caso, ottieni un piatto di spaghetti con indentazione se-else-else. Direi che questa non è una brutta cosa, poiché avverte il lettore che c'è un pasticcio di business logic nel cuore di tutto questo. I problemi di business logic sono solitamente superiori al grado di retribuzione del tecnico del software; devono essere indirizzati dalla direzione aziendale.

Nota: c'è un bel bocconcino in un libro che ho letto molti anni fa. Un ragazzo che frequentava una scuola di specializzazione stava avendo un inferno con una classe di contabilità / auditing, combattendo con una simulazione di un computer digitale. Alla fine ha fatto irruzione nell'edificio della chimica, ha liberato un mucchio di oggetti in vetro e ha costruito un modello di computer ANALOG, usando i flussi d'acqua attraverso le valvole per simulare il denaro che fluiva attraverso l'azienda simulata, ed è stato in grado di ottenere le sue risposte in questo modo. L'effetto collaterale è stato che vedere le circonvoluzioni del modello analogico, nella profusione di tubi, valvole, T e roba, gli ha fornito informazioni significative su quanto fosse incasinata la società simulata.

Vuoi rendere visibili quei messaggi.

    
risposta data 07.02.2017 - 18:51
fonte
0

Sarei incline a sfruttare il fatto che JavaScript è in realtà un linguaggio orientato agli oggetti e un polimorfismo.

Se crei un oggetto tester di base che esegue i test e che ha o metodi virtuali puri per ognuno o che ha semplicemente stub per ognuno che restituiscono Fail.

Quindi, per ciascuno dei tipi di varianti nella struttura dati, è possibile definire classi di test che ereditano dal tester di base e personalizza i singoli test in base alle esigenze.

Quindi i test saranno in grado di utilizzare le classi di test per le varianti in modo appropriato, dovresti ottenere una buona chiarezza nel codice di prova e una buona manutenzione.

    
risposta data 07.02.2017 - 19:54
fonte

Leggi altre domande sui tag