JavaRush /Java Blog /Random-IT /Errori tipici nel codice Java.
Sdu
Livello 17

Errori tipici nel codice Java.

Pubblicato nel gruppo Random-IT
Questo materiale contiene gli errori più tipici che ho riscontrato nel codice Java delle persone che lavorano con me. L'analisi statica (usiamo qulice ), per ovvi motivi, non è in grado di rilevare tutti questi errori, motivo per cui ho deciso di elencarli qui. Tutti questi errori sono legati alla programmazione orientata agli oggetti in generale e a Java in particolare.
Nomi delle classi
La tua classe dovrebbe essere un'astrazione di un oggetto della vita reale senza " validatori " , " controllori " , " manager " , ecc . Se il nome della tua classe termina con "-er" è un cattivo design. E, naturalmente, le classi helper anti-pattern come StringUtils , FileUtils e IOUtils di Apache sono ottimi esempi di modelli di progettazione terribili. Non aggiungere mai suffissi o prefissi per distinguere tra interfacce e classi. Ad esempio, tutti questi nomi sono terribili: IRecord , IfaceEmployee o RecordInterface . In genere, il nome dell'interfaccia è il nome dell'oggetto reale, mentre il nome della classe dovrebbe spiegare i dettagli dell'implementazione. Se non si può dire nulla di specifico sull'implementazione, andranno bene i nomi " Default ", " Simple " o qualcosa di simile. Per esempio: class SimpleUser implements User {}; class DefaultRecord implements Record {}; class Suffixed implements Name {}; class Validated implements Content {};
Nomi dei metodi
I metodi possono restituire " qualcosa " o restituire " void ". Se un metodo restituisce qualcosa, il suo nome dovrebbe spiegare cosa verrà restituito. Ad esempio (non utilizzare il prefisso " get "): boolean isValid(String name); String content(); int ageOf(File file); Se viene restituito " void ", il nome dovrebbe chiarire cosa fa il metodo. Ad esempio: void save(File file); void process(Work work); void append(File file, String line); esiste solo un'eccezione a questa regola: i metodi di test JUnit . Sono descritti di seguito.
Nomi dei metodi di prova
I nomi dei metodi nei test JUnit devono essere costruiti come una frase inglese senza spazi. Questo è più facile da spiegare con un esempio: è /** * HttpRequest can return its content in Unicode. * @throws Exception If test fails */ public void returnsItsContentInUnicode() throws Exception { } importante iniziare la prima frase del tuo JavaDoc con il nome della classe che stai testando seguito da “ can ”. Quindi, la prima frase dovrebbe sempre essere come la frase " qualcuno può fare qualcosa ". Il nome del metodo indicherà la stessa cosa, ma senza l'oggetto del test. Se lo aggiungo all'inizio del nome del metodo, ottengo una frase inglese completa, come nell'esempio sopra: " HttpRequest restituisce il suo contenuto in unicode ". Si tenga presente che il nome del metodo di prova non inizia con “ can ”. Solo i commenti JavaDoc iniziano con " can ". Inoltre, i nomi dei metodi non dovrebbero iniziare con un verbo ( dal traduttore: a quanto pare l'autore intende il modo imperativo del verbo ). È buona norma indicare che viene generata un'eccezione quando si dichiara un metodo di test.
Nomi di variabili
Evita nomi di variabili composte come timeOfDay , firstItem o httpRequest . Intendo sia variabili di classe che variabili di metodo. Il nome della variabile dovrebbe essere abbastanza lungo da evitare ambiguità nel suo ambito, ma non troppo lungo se possibile. Il nome deve essere un sostantivo singolare o plurale. Ad esempio: a volte potrebbero verificarsi collisioni tra i parametri del costruttore e i campi della classe se il costruttore memorizza i dati di input nell'oggetto creato. In questo caso consiglio di creare un'abbreviazione eliminando le vocali. Esempio: nella maggior parte dei casi, il nome della variabile migliore sarà il nome della classe corrispondente. Basta scrivere in maiuscolo e starai bene: tuttavia, non fare mai lo stesso per i tipi primitivi come o . Puoi anche usare gli aggettivi quando ci sono più variabili con caratteristiche diverse. Per esempio: List names; void sendThroughProxy(File file, Protocol proto); private File content; public HttpRequest request; public class Message { private String recipient; public Message(String rcpt) { this.recipient = rcpt; } } File file; User user; Branch branch; Integer number String string String contact(String left, String right);
Costruttori
Senza eccezioni, dovrebbe esserci un solo costruttore che memorizza i dati nelle variabili oggetto. Tutti gli altri costruttori devono chiamarlo con parametri diversi: public class Server { private String address; public Server(String uri) { this.address = uri; } public Server(URI uri) { this(uri.toString()); } }
Variabili una tantum
Evita a tutti i costi le variabili una tantum. Per “usa e getta” intendo variabili che vengono utilizzate una volta. Come in questo esempio: String name = "data.txt"; return new File(name); una variabile viene utilizzata solo una volta e il codice può essere semplificato in: return new File("data.txt"); A volte, in casi molto rari, principalmente a causa di una migliore formattazione, è possibile utilizzare variabili monouso. Tuttavia, cerca di evitare tali situazioni.
Eccezioni.
Naturalmente, non bisogna mai "inghiottire" le eccezioni; dovrebbero essere lanciate il più in alto possibile. Le eccezioni dai metodi privati ​​devono essere gestite esternamente. Non utilizzare mai le eccezioni per controllare il flusso. Il codice nell'esempio non è corretto: int size; try { size = this.fileSize(); } catch (IOException ex) { size = 0; } Seriamente, cosa succede se IOException dice "disco pieno", presumi che la dimensione del file sia zero e continui?
Rientro.
Per il rientro, la regola generale è che la parentesi deve terminare la riga o chiudersi sulla stessa riga (per la parentesi di chiusura vale la regola opposta). Nell'esempio seguente, il codice non è corretto perché la prima parentesi non è chiusa sulla stessa riga e sono presenti dei caratteri dopo di essa. La seconda parentesi ha lo stesso problema perché ci sono dei caratteri prima di essa e non ci sono parentesi di apertura sulla riga corrente. final File file = new File(directory, "file.txt"); Il rientro corretto dovrebbe assomigliare a questo: StringUtils.join( Arrays.asList( "first line", "second line", StringUtils.join( Arrays.asList("a", "b") ) ), "separator" ); La seconda regola importante del rientro è che dovresti inserire quanto più possibile su una riga - entro 80 caratteri. L'esempio sopra non è valido in quanto può essere compresso: StringUtils.join( Arrays.asList( "first line", "second line", StringUtils.join(Arrays.asList("a", "b")) ), "separator" );
Costanti ridondanti.
Le costanti di classe dovrebbero essere usate quando vuoi condividere l'accesso alle informazioni tra i metodi della classe e queste informazioni sono una caratteristica ( ! ) della tua classe. Non utilizzare costanti in sostituzione di stringhe o valori letterali numerici: una pessima pratica che porta all'inquinamento del codice. Le costanti (come altri oggetti OOP) devono avere un significato nel mondo reale. Qual è il significato di queste costanti nel mondo reale: class Document { private static final String D_LETTER = "D"; // bad practice private static final String EXTENSION = ".doc"; // good practice } un altro errore comune è utilizzare costanti nei test unitari per evitare di duplicare valori letterali stringa/numerici nei metodi di test. Non farlo! Ciascun metodo di prova deve operare sul proprio insieme di valori di input. Utilizzare nuovi testi e numeri in ogni nuovo metodo di prova. I test sono indipendenti. Allora perché dovrebbero condividere le stesse costanti di input?
Testare l'accoppiamento dei dati.
Ecco un esempio di hook in un metodo di test: User user = new User("Jeff"); // maybe some other code here MatcherAssert.assertThat(user.name(), Matchers.equalTo("Jeff")); Nell'ultima riga concateniamo " Jeff " con la stessa stringa letterale specificata nella prima riga. Se, qualche mese dopo, qualcuno desidera modificare il valore nella terza riga, dovrà dedicare più tempo alla ricerca di dove altro viene utilizzato " Jeff " in questo metodo. Per evitare questo intoppo dei dati, dovresti introdurre una variabile.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION