JavaRush /Blog Java /Random-ES /Errores típicos en el código Java.
Sdu
Nivel 17

Errores típicos en el código Java.

Publicado en el grupo Random-ES
Este material contiene los errores más típicos que he visto en el código Java de las personas que trabajan conmigo. El análisis estático (usamos qulice ), por razones obvias, no puede detectar todos estos errores, por lo que decidí enumerarlos aquí. Todos estos errores están relacionados con la programación orientada a objetos en general y con Java en particular.
Nombres de clase
Su clase debe ser una abstracción de un objeto de la vida real sin " validadores " , " controladores " , " administradores " , etc. Si el nombre de su clase termina con "-er", es un mal diseño. Y, por supuesto, las clases auxiliares antipatrones como StringUtils , FileUtils e IOUtils de Apache son excelentes ejemplos de patrones de diseño terribles. Nunca agregue sufijos o prefijos para diferenciar entre interfaces y clases. Por ejemplo, todos estos nombres son terribles: IRecord , IfaceEmployee o RecordInterface . Normalmente, el nombre de la interfaz es el nombre del objeto de la vida real, mientras que el nombre de la clase debe explicar los detalles de implementación. Si no se puede decir nada específico sobre la implementación, los nombres " Predeterminado ", " Simple " o algo similar servirán. Por ejemplo: class SimpleUser implements User {}; class DefaultRecord implements Record {}; class Suffixed implements Name {}; class Validated implements Content {};
Nombres de métodos
Los métodos pueden devolver " algo " o " vacío ". Si un método devuelve algo, entonces su nombre debe explicar qué se devolverá. Por ejemplo (no utilice el prefijo " get "): boolean isValid(String name); String content(); int ageOf(File file); si se devuelve " void ", el nombre debe aclarar qué hace el método. Por ejemplo: void save(File file); void process(Work work); void append(File file, String line); solo hay una excepción a esta regla: los métodos de prueba JUnit . Se describen a continuación.
Nombres de métodos de prueba
Los nombres de los métodos en las pruebas JUnit deben construirse como una oración en inglés sin espacios. Esto es más fácil de explicar con un ejemplo: es /** * HttpRequest can return its content in Unicode. * @throws Exception If test fails */ public void returnsItsContentInUnicode() throws Exception { } importante comenzar la primera oración de su JavaDoc con el nombre de la clase que está probando seguido de " can ". Entonces, la primera oración siempre debe ser como la frase " alguien puede hacer algo ". El nombre del método indicará lo mismo, pero sin el tema de prueba. Si lo agrego al principio del nombre del método, obtengo una oración completa en inglés, como en el ejemplo anterior: " HttpRequest devuelve su contenido en Unicode ". Tenga en cuenta que el nombre del método de prueba no comienza con " can ". Sólo los comentarios de JavaDoc comienzan con " can ". Además, los nombres de los métodos no deben comenzar con un verbo ( del traductor: aparentemente, el autor se refiere al modo imperativo del verbo ). Es una buena práctica indicar que se produce una excepción al declarar un método de prueba.
Nombres de variables
Evite nombres de variables compuestas como timeOfDay , firstItem o httpRequest . Me refiero tanto a variables de clase como a variables de método. El nombre de la variable debe ser lo suficientemente largo para evitar ambigüedades en su alcance, pero no demasiado largo si es posible. El nombre debe ser un sustantivo en singular o plural. Por ejemplo: a veces puede haber colisiones entre los parámetros del constructor y los campos de clase si el constructor almacena datos de entrada en el objeto creado. En este caso recomiendo crear una abreviatura eliminando las vocales. Ejemplo: en la mayoría de los casos, el mejor nombre de variable será el nombre de la clase correspondiente. Simplemente póngalo en mayúscula y estará bien: sin embargo, nunca haga lo mismo con tipos primitivos como o . También puedes utilizar adjetivos cuando hay varias variables con características diferentes. Por ejemplo: 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);
Constructores
Sin excepción, debería haber un solo constructor que almacene datos en variables de objeto. Todos los demás constructores deben llamar a este con parámetros diferentes: public class Server { private String address; public Server(String uri) { this.address = uri; } public Server(URI uri) { this(uri.toString()); } }
Variables únicas
Evite las variables únicas a toda costa. Por "desechables" me refiero a variables que se usan una vez. Como en este ejemplo: String name = "data.txt"; return new File(name); una variable se usa solo una vez y el código se puede simplificar a: return new File("data.txt"); A veces, en casos muy raros, principalmente debido a un mejor formato, se pueden usar variables de una sola vez. Sin embargo, trate de evitar tales situaciones.
Excepciones.
Por supuesto, nunca debes "tragarte" las excepciones; deben lanzarse lo más alto posible. Las excepciones de métodos privados deben manejarse externamente. Nunca utilice excepciones para controlar el flujo. El código del ejemplo es incorrecto: int size; try { size = this.fileSize(); } catch (IOException ex) { size = 0; } en serio, ¿qué pasa si IOException dice "el disco está lleno", asumirá que el tamaño del archivo es cero y continuará?
Sangría.
Para la sangría, la regla general es que el paréntesis debe terminar la línea o cerrar en la misma línea (se aplica la regla opuesta para el paréntesis de cierre). En el siguiente ejemplo, el código es incorrecto porque el primer paréntesis no está cerrado en la misma línea y hay caracteres después. El segundo corchete tiene el mismo problema porque hay caracteres delante y no hay ningún corchete de apertura en la línea actual. final File file = new File(directory, "file.txt"); La sangría correcta debería verse así: StringUtils.join( Arrays.asList( "first line", "second line", StringUtils.join( Arrays.asList("a", "b") ) ), "separator" ); La segunda regla importante de la sangría es que debes colocar la mayor cantidad posible en una línea, dentro de los 80 caracteres. El ejemplo anterior no es válido ya que se puede comprimir: StringUtils.join( Arrays.asList( "first line", "second line", StringUtils.join(Arrays.asList("a", "b")) ), "separator" );
Constantes redundantes.
Las constantes de clase deben usarse cuando desee compartir el acceso a la información entre métodos de clase, y esta información es una característica ( ! ) de su clase. No utilice constantes como reemplazo de cadenas o literales numéricos; es una muy mala práctica que conduce a la contaminación del código. Las constantes (como otros objetos OOP) deben tener significado en el mundo real. ¿Cuál es el significado de estas constantes en el mundo real? class Document { private static final String D_LETTER = "D"; // bad practice private static final String EXTENSION = ".doc"; // good practice } Otro error común es usar constantes en pruebas unitarias para evitar la duplicación de cadenas/literales numéricos en los métodos de prueba. ¡No hagas eso! Cada método de prueba debe operar con su propio conjunto de valores de entrada. Utilice nuevos textos y números en cada nuevo método de prueba. Las pruebas son independientes. Entonces, ¿por qué deberían compartir las mismas constantes de entrada?
Acoplamiento de datos de prueba.
A continuación se muestra un ejemplo de enlace en un método de prueba: User user = new User("Jeff"); // maybe some other code here MatcherAssert.assertThat(user.name(), Matchers.equalTo("Jeff")); En la última línea, concatenamos " Jeff " con la misma cadena literal especificada en la primera línea. Si, unos meses más tarde, alguien quiere cambiar el valor en la tercera línea, tendrá que dedicar más tiempo a buscar dónde más se usa " Jeff " en este método. Para evitar este problema de datos, debe introducir una variable.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION