Metodo migliore per la convalida dei parametri di funzione

5

Mi sono dilettato con l'idea di creare il mio CMS per l'esperienza e perché sarebbe divertente gestire il mio sito web dalla mia base di codice.

Una delle decisioni su cui continuo a tornare è il modo migliore per convalidare i parametri in entrata per le funzioni.

Questo è principalmente in riferimento a tipi di dati semplici poiché la convalida degli oggetti sarebbe un po 'più complessa.

All'inizio ho discusso della creazione di una convenzione di denominazione che contenga informazioni su quali dovrebbero essere i parametri, (int, string, bool, ecc.) e ho anche immaginato di poter creare opzioni su cui convalidare. Ma poi in ogni funzione ho ancora bisogno di eseguire una sorta di validazione dei parametri che analizza il nome del parametro per determinare quale valore può essere quindi validato contro di esso, garantito che questo sarebbe gestito passando l'elenco dei parametri per funzionare ma che deve ancora Accade e uno dei miei obiettivi è rimuovere la convalida dei parametri dalla funzione stessa in modo che sia possibile avere solo il codice di funzione effettivo che realizza l'attività desiderata senza il codice aggiuntivo per la convalida.

C'è un buon modo per gestirlo, o è un livello così basso che in genere la validazione dei parametri viene eseguita all'inizio della chiamata alla funzione, quindi dovrei continuare a farlo.

    
posta Aglystas 05.09.2012 - 20:36
fonte

4 risposte

2

Le soluzioni generali a questo problema sono la sicurezza del tipo (in modo che i valori siano validi per costruzione) e l'incapsulamento (in modo che i valori non possano essere invalidati dopo la costruzione). Se i tuoi input e output hanno tipi significativi, i costruttori di questi tipi possono applicare le proprietà che desideri. Se la convalida è centralizzata, non è necessario ripeterla.

Parliamo in pseudocodice per un momento. Come esempio forzato, considera una funzione area(w, h) che calcola l'area di un rettangolo. Se si digita la funzione come:

int area(int w, int h)

Quindi non vi è alcuna garanzia che uno degli invarianti abbia:

  • w e h sono lunghezze

  • Essendo lunghezze, devono essere non negative

  • Il risultato è un'area

Per applicare i vincoli di input, puoi sempre aggiungere la convalida al corpo della funzione:

int area(int w, int h) {
    assert(w >= 0);
    assert(h >= 0);
    return w * h;
}

Non solo questo è macchinoso, ma rimane la responsabilità del chiamante di convalidare il risultato. Se utilizziamo i tipi che rappresentano le nostre unità:

Area area(Length w, Length h) {
    return w * h;
}

Quindi nessuno può darci un Volume quando ci aspettavamo un Length , e dal momento che una lunghezza non può essere negativa, non è necessario controllarla.

PHP non impone staticamente i tipi, ma puoi impedire la costruzione di oggetti non validi generando eccezioni da costruttori che ricevono input non validi e utilizzando oggetti o accessori non modificabili per impedire l'invalidazione successiva.

    
risposta data 05.09.2012 - 21:43
fonte
1

In base al commento "uno dei miei obiettivi è rimuovere la convalida dei parametri dalla funzione stessa in modo che sia possibile avere solo il codice funzione effettivo che esegue l'attività desiderata senza il codice aggiuntivo per la convalida" , potresti voler utilizzare utilizzando AOP per la convalida del metodo . Speriamo che le tecnologie che stai utilizzando possano supportare questo paradigma.

In questo caso, il tuo validatore sarebbe un aspetto e non inquinerebbe la logica aziendale della tua funzione. Ciò dovrebbe aggiungere il vantaggio di rendere la logica di convalida prontamente riutilizzabile e aiuterà a supportare il test dell'unità.

    
risposta data 05.09.2012 - 20:43
fonte
0

Penso che potresti utilizzare la progettazione per contratto, nel senso che il codice del tuo CMS non sta facendo gran parte della convalida, confidando nell'input del livello esterno. Lo strato esterno dovrebbe essere rigoroso, forse anche un po 'paranoico sull'input.

Per strato esterno intendo i punti di estensione del tuo cms, ad es. la classe controller che viene estesa, gli oggetti che accettano l'estensione tramite strategie o visitatore, ecc. Naturalmente, come già notato, è possibile utilizzare AOP (è ora disponibile in PHP con "hack" come getDocComment)

Ovviamente potrebbe trattarsi di un po 'di over-engineering, ma è quello che farei.

    
risposta data 05.09.2012 - 20:46
fonte
-1

Bene ... Vorrei creare una classe di validatori. Tutto l'input dell'utente passerebbe attraverso quello. Se la convalida fallisce, il codice ritorna.

Ora, puoi utilizzare un'unica interfaccia di Validator e creare diverse regole di convalida o utilizzare un solo oggetto Validator che conosca tutte le regole di convalida necessarie.

Di quando, quando sei sicuro che un 'numero telefonico' è in realtà un 'numero' e non un carattere, allora chiami la funzione che lo ha come parametro.

In genere, le funzioni / i metodi non dovrebbero controllare la validità dei parametri, tuttavia in alcune situazioni sarà comunque necessario controllare alcune cose. Se qualcosa va storto con una funzione, dovrebbe generare ed eccezione.

Quindi, filtra l'input dell'utente il più vicino possibile all'utente e getti eccezioni per casi imprevisti il più profondamente possibile nella tua logica.

AGGIORNAMENTO: Inoltre, puoi prendere in considerazione l'implementazione del modello di progettazione dell'osservatore o, se necessario, un mediatore.

    
risposta data 05.09.2012 - 22:25
fonte

Leggi altre domande sui tag