2013-05-17 16 views
27

Oggi ho aggiunto un controllo di sicurezza in più dietro i miei moduli di login, a rallentare attacchi di forza bruta. Ho diversi moduli di accesso e ho creato una funzione facile da chiamare che esegue tutto il controllo e restituisce il risultato.Le migliori pratiche per restituire più valori in Java?

public static ValidateLoginResult validateLogin(HttpServletRequest request, String email, String password) { 

Il problema è il risultato non è un unico valore, il risultato è costituito da:

boolean ok 
String errorMessage 
boolean displayCaptcha 

Per questo ho creato una nuova classe. Tutto funziona bene.

Ma spesso ho utili funzioni di utilità che restituiscono più valori e inizio a trovare un po 'fastidioso creare ogni volta una nuova classe per il risultato.

Esiste un modo migliore per restituire più valori? O sono solo pigro? :)

+2

non essere pigro. :) –

+8

Non c'è, ma non sei pigro :) Anche per me è una seccatura. –

+0

Non creare una nuova classe, utilizzare invece [classi generiche] (http://docs.oracle.com/javase/tutorial/java/generics/types.html). – Mateusz

risposta

14

No, questo tipo di struttura non esiste nativamente in Java, ma è possibile guardare a JavaTuples library che può soddisfare le proprie necessità e fornire una soluzione abbastanza elegante. Utilizzo di Triplet<Boolean, String, Boolean>

+1

Ma con una classe piccola puoi accedere ai membri con un getter o rendere i valori facoltativi – moeTi

+8

Scrivere 'return new Triplet (valori effettivi)' non è un fulgido esempio di eleganza, o :) –

+1

Questo è in realtà un argomento di discussione: http://stackoverflow.com/questions/156275/what-is-the-equivalent-of-the-c-pairl-r-in-java – SubSevn

5

Non si è sicuri delle "migliori pratiche", ma un'opzione pragmatica è quella di restituire un Map<String, String>? Per esempio.

myMap.put("result", "success"); 
myMap.put("usernameConfirmed", "bigTom"); 

return myMap; 

vola Probabilmente a fronte di un milione di principi OO ma ho sentito si ri volendo evitare una proliferazione di classi di risultato.

Si potrebbe in alternativa utilizzare Map<String, Object> ed essere più severi con controlli di tipo su oggetti archiviati: stringhe, booleani, date, ecc

+3

È possibile evitare errori di battitura e auto-documento se si utilizza un Enum per i valori chiave. – tucuxi

+0

buona idea, una buona vittoria per pochissimo lavoro extra – Brian

0

probabilmente sarei solo andare il percorso di classe me stesso, ma a seconda di ciò che si desidera che la funzione per tornare, potresti essere in grado di farla franca restituendo una sorta di contenitore di valori.

4

Non riesco davvero a pensare a un modo migliore, più pulito e più orientato agli oggetti per restituire più valori da una funzione che incapsularli in una classe.

Idealmente, i valori multipli che si desidera restituire sono concettualmente tutti parte della stessa classe, quindi ha senso raggrupparli in questo modo; se non lo fanno, probabilmente dovresti decomporre la tua funzione in alcune funzioni più piccole che restituiscono ciascuno dei valori di cui hai bisogno al di fuori della funzione stessa.

Per quanto posso dire, alcuni IDE hanno anche strutture per aiutare l'incapsulamento più valori in una classe: per esempio, Eclipse ha Refactor --> Extract class...

+3

Non c'è nulla di orientato agli oggetti su questo; riguarda principalmente la tipizzazione statica di Java e i generici deboli. JavaScript è orientato agli oggetti e non ha bisogno di un'altra classe per ogni tupla. –

+1

sembra che ogni programmatore Java voglia creare un oggetto per tutto ... cosa c'è che non va con i buoni dati? – jassa

+1

Java ti offre anche un'alternativa pronta all'uso? Forse non è colpa del programmatore. – jassa

5

È possibile definire una classe Pair<A, B>, e una classe Triplet<A, B, C>, e che sarebbe risolvere il problema della restituzione dei valori 2 e 3 garantendo al contempo la sicurezza del tipo. In questo caso particolare, la firma potrebbe essere

public static boolean validateLogin(HttpServletRequest request, 
      String email, String password, Pair<Message, Boolean> outputIfOk); 

O, meglio ancora, in un contesto servlet, può essere utile per impostare alcune richieste ben documentata attributi.

Se si riscontra la necessità di classi speciali per restituire i risultati molto spesso, è molto probabile che si possa ridefinire quelle coppie per condividere un antenato comune (ad esempio, avere un RequestStatus che include i campi "ok" e "messaggio").

Oltre a ciò, si, si è pigri: le chiusure personalizzate saranno sempre più autodocumentanti delle coppie e delle terzine.

+0

Bene, c'è anche una ImmutablePair nel pacchetto di org.apache.commons.lang3.tuple – zygimantus

1

È possibile restituire una matrice Object [], java autobox così è più facile da usare. Se è solo per un passaggio a breve distanza, perché no. Ofc il suo rischio, possibili problemi di cast di classe, nullchecks ecc

ma è facile da scrivere e utilizzare.

poi di nuovo, una classe interna statica è rapidamente creato e se lo metti proprio accanto al metodo di restituirlo, si sa anche dove trovarlo (di solito vicino all'origine)

Problemi correlati