Pautas de código para contribuir en Android

Este es un artículo basado en “Code Style Guidelines for Contributors” que se puede encontrar en la siguiente URL: Code Style Guidelines.

Google nos empieza estas pautas con el siguiente mensaje: «Las siguientes reglas no son pautas o recomendaciones, sino reglas estrictas. Las contribuciones para Android normalmente no serán aceptadas si no se cumplen estas reglas.»

¿Por qué es importante seguir estas reglas? Es una opinión personal, pero espero que la mayoría de desarrolladores estén de acuerdo conmigo en que es necesario que todos llevemos un estándar de programación. Para cada plataforma este estándar será distinto, sin duda alguna, pero siento que si todos los que programamos en X o Y plataforma seguimos las pautas que nos recomiendan, nos vamos a ahorrar muchísimo tiempo descifrando el código del otro y nuestra productividad se verá aumentada.

Ahora sí, comencemos…

Android sigue las mismas convenciones de Java sólo que con unas adiciones:

No ignores excepciones

void setServerPort (String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) { }
}

Esto no se debe hacer nunca. Aunque pienses que tu código nunca encontrará esta condición de error o que no es importante manejarla, ignorar las excepciones como se muestra arriba crea una especie de huecos en el código que algún día alguien podrá tropezar con ellos. Lo correcto es manejar cada excepción en tu código.

Las alternativas aceptadas son:

void setServerPort(String value) throws NumberFormatException {
     serverPort = Integer.parseInt(value);
}
void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) {
        serverPort = 80;
    }
}

No captures excepciones genéricas

Algunas veces las personas hacen lo siguiente:

try {
    funcionQuePuedeLanzarUnIOException();
    funcionQuePuedeLanzarUnParsingException();
    funcionQuePuedeLanzarUnSecurityException();
} catch (Exception e) {
    manejoDeLaExcepcion();
}

Esto no se debe hacer. En casi todos los casos es inapropiado capturar Exception o Throwable genéricos. Es muy peligroso porque hay excepciones que nunca esperaste recibir (incluyendo RuntimeExceptions como ClassCastException) que pueden terminar siendo capturadas en el manejo de errores de la aplicación.

Alternativas a capturar excepciones genéricas:

  • Capturar cada excepción de forma separada como bloques de captura separados después de un try individual. Se ve raro, pero es la mejor forma de hacerlo.
  • Haz refractor a tu código para tener un mejor manejo de errores, con multiples bloques try.

Califica por completo los imports

Cuando vas a usar la clase Bar del paquete Foo, hay dos posibles formas de hacerlo:

  1. import foo.*;
  2. import foo.Bar;

La recomendada es la 2 ya que hace obvias las clases que se están usando y hace el código más legible para las personas que lo mantendrán.

Usa los comentarios estándares de Javadoc

  • Todo archivo debe tener una declaración de copyright en la cabecera.
  • Arriba de la declaración de la clase o interfaz debe haber un comentario describiendo que hace.
  • Se debe colocar antes de la declaración del método un comentario describiendo lo que hace.
    Si el método es un getter o un setter no es necesario describir su funcionamiento.

Limita el scope de las variables

Las variables locales deben ser declaradas en el punto donde son usadas por primera vez. Si no tienes suficiente información para inicializar la variable, deberías posponer la declaración hasta que puedas hacerlo.

Las variables en los ciclos deberían ser declaradas dentro de la sentencia for a menos de que haya alguna razón importante para hacer lo contrario.

for (int i = 0; i < n; i++) {
    algunMetodo();
}

ó

for (Iterator i = c.iterator(); i.hasNext(); ) {
    algunMétodo(i.next());
}

Orden de las declaraciones de imports

El orden de las declaraciones debería ser:

  1. Paquetes de Android
  2. Paquetes de terceros
  3. java y javax

Debe haber una línea en blanco de espacio entre cada grupo.

Uso de espacios para la indentación

  • Se usan 4 espacios para indentar en bloques. Nunca se usan tabulaciones.

  • Se usan 8 espacios para quiebres de líneas, incluyendo llamadas a funciones y asignaciones.

Esto es correcto:

Instrument i =
        unaExpresionMuyLarga(que, no, cabria, enUna, linea);

Esto no es correcto:

Instrument i =
    unaExpresionMuyLarga(que, no, cabria, enUna, linea);

Sigue las convenciones para los nombres de los campos:

  • Los campos no públicos, no estáticos siempre empiezan con m.
  • Los campos estáticos empiezan con una s.
  • Otros campos empiezan con la primera letra minúscula.
  • Las constantes (campos públicos estáticos finales) siempre se nombran con mayúsculas y con subrayado.
    Ejemplo: SOY_UN_CAMPO_CONSTANTE

Uso de llaves

Las llaves no van en su propia línea, van en la misma línea como el código anterior a ellas.

class soyUnaClase {
    int función() {
        if (algo) {
            …
        } else {
            …
        }
    }
}

Si el condicional entero ocupa una línea, puedes (no es obligación) ponerlo en la misma línea:

if (algo) función();

Pero no debes hacer nunca:

if (algo)
    funcion();

Límite de ancho de línea

Cada línea en tu código debe tener un máximo de 100 caracteres de longitud.

Hay 2 excepciones para esta regla:

  • Si un comentario contiene un comando de ejemplo o una URL mayor a 100 caracteres, esa línea debe ser mayor a 100 caracteres para poder copiar y pegar fácilmente.
  • Las líneas en los import pueden sobrepasar este límite porque los humanos la mayoría de veces no las leen.

Deja una respuesta