Contenido

Guía de estilo de programación en jC 2

1Introducción 2

2Indicaciones generales 2

3Identificadores 3

3.1Identificadores de constantes 3

3.2Identificadores de variables 3

3.3Identificadores de funciones 4

4Comentarios 5

4.1Comentarios explicativos de funciones 5



Guía de estilo de programación en jC

1Introducción

En este documento se explica brevemente, mediante ejemplos, cómo escribir programas más legibles. A lo largo de su vida profesional, cualquier programador se plantea la pregunta de cómo escribir sus programas de manera que sean más legibles, y por tanto que puedan ser mantenidos (corrección de errores, ampliación de funcionalidad) con facilidad, tanto por él mismo como por otros programadores (una situación típica en cualquier empresa).

Dado que la misma situación en cuanto a legibilidad de código suele ser resuelta por distintos programadores de la misma forma, pero con distintos matices de diferenciación, es interesante seguir una guía de estilo que nos explique como otros resolvieron ese mismo problema, hasta que dicha solución se convirtió en un estándar.

2Indicaciones generales

El propósito de seguir una norma de estilo es hacer que el código fuente de un programa sea tan legible como sea posible. Así, hay tres puntos básicos que se deben cuidar: el espaciado horizontal, el espaciado vertical y la indentación. El espaciado horizontal consiste en que las líneas en las que esté dividido el código fuente deben ser de una longitud máxima lo más próxima posible a 80 caracteres, ya que al imprimir el código en papel cualquier línea superior a 80 columnas se descarta automáticamente.

Uno de los problemas que se puede encontrar al codificar es la manera más correcta para dividir una línea muy larga. Respuestas comunes a esta pregunta son: antes de una subexpresión, antes de un operador, o antes de un paréntesis. Por ejemplo:


int x = ( (a * b + c ) / ( c * d * d ) )

+ ( a / ( b * c ) )

+ ( ( 3.1451927 * b ) + d )

;


Los operadores deben separarse mediante espacios para mayor claridad.

El espaciado vertical consiste en cuántas líneas ocupa una función o una estructura, en el código fuente. En general, es útil autoimponerse un límite de una hoja (30-50 líneas) por cada función o procedimiento. Es extraño, siempre que la misma no consista en multitud de acciones repetitivas (como escribir en un archivo), que una función bien diseñada ocupe más allá de un folio. En caso contrario, será conveniente considerar que posiblemente sea interesante subdividirlo en varias subfunciones (probablemente de acceso privado).

Además, en el espaciado vertical intervienen las llaves que se emplean para marcar el comienzo y fin del cuerpo de una función, de un bucle,... cada una de esas llaves puede llegar a consumir una línea por sí sola, incluso dos. Así, para salvar algo de espacio vertical, se suelen mantener las llaves de apertura y cierre, cada una en una línea, para el cuerpo de las funciones, y en cambio colocar la llave de apertura en la misma línea para bucles y estructuras de decisión. Por ejemplo:



int dividir(int a, int b)

{

if ( b != 0 ) {

return a / b;

}

return 0;

}


...(recuérdese que en un programa real será mucho más adecuado responder a la contingencia que plantea dividir un número entre cero, que responder con cero “silenciosamente”, lo cual supone un error no detectado).

La indentación es vital para poder comprender rápidamente los elementos funcionales de un programa. Así, el cuerpo (las instrucciones) de una función o procedimiento debe estar alineado en su margen izquierdo más a la derecha que su cabecera, de la misma forma que un bucle dentro de esa función y así sucesivamente. Por ejemplo:


int elevarA(int x, int y)

{

int toret = 1;


if ( y >= 0 ) {

for(; y > 0; --y) {

toret *= x;

}

} else {

toret = 0;

}


return toret;

}

3Identificadores

Los identificadores se utilizan en varias (innumerables) ocasiones en programación: funciones, constantes, constantes, variables..., y son claves para entender qué valores puede contener una variable, o qué hace una función. Por eso, hay que poner especial cuidado en su elección. También será interesante seguir unas pequeñas reglas a la hora de escribir un identificador que hagan que a su vez podamos obtener el máximo significado del mismo si se está leyendo en un listado.

En general, los identificadores deben ser tan cortos como sea posible, pero a la vez tan informativos como sea posible. Muchas veces, además, es imposible utilizar un solo sustantivo para nombrar una variable, función o estructura; en ese caso, se concatenarán todos para formar el identificador final, poniendo cada inicial en mayúscula.

3.1Identificadores de constantes

Los identificadores de constantes deberían corresponderse con sustantivos de la vida real o del concepto que se está modelando con el programa. Así, identificadores de constantes típicos pueden ser: PI, E...

El identificador de la constante, en caso de estar compuesto por más de una palabra, se construye concatenando todas las palabras, y poniendo la inicial de cada una de estas palabras en mayúsculas. Por ejemplo: MinCuentaCorriente, MaxCredito...


final int NumRuedas = 4;

final int MaxCaracteres = 255;

final double FactorIVA = 0.21;

3.2Identificadores de variables

Los identificadores de variables, siguen las mismas normas que los de las constantes, pero con la primera inicial en minúscula. Así, por ejemplo, identificadores válidos son nombrePersona, precioEnEuros,...


char[] nombrePersona;

double precioEnEuros;

Existen, aún así, varias particularidades. Por ejemplo, a las variables locales empleadas en bucles se les suele asignar identificadores de una letra tipo 'i' y 'j', también en el caso de algunos argumentos simples (si bien este caso es mejor, sin embargo, evitarlo, cuando sea posible, y asignar identificadores descriptivos) de funciones.


void cnvtMayusculas(char[] cadena)

{

for(int i = 0; i < size( cadena ); ++i) {

cadena[ i ] = toUpperCase( s[ i ] );

}

}


Los identificadores de variables también pueden informar sobre para qué se utiliza esa variable, y no restringirse a tan solo información sobre qué valores alberga. Por ejemplo, en el código siguiente toret (a retornar) es una variable que se utiliza en todas las funciones para devolver un valor.


int calcularSumatorio(double[] v)

{

int toret = 0;


for(int i = 0; i < size( v ); ++i) {

toret += v[ i ];

}


return toret;

}

3.3Identificadores de funciones

Los identificadores de funciones siguen las mismas reglas que para los de variables. Sin embargo, deben escogerse de modo que sugieran de manera intuitiva qué hacen. Así, el identificador debe ser un verbo o al menos contener uno. Las funciones que devuelven un valor lógico deberían tener un verbo copulativo (ser o estar) al comienzo del identificador.


double calculaArea(double lado1, double lado2)...

int esPalindromo(char[] cadena)...


Evítensen identificadores como los siguientes:


int procesar(int x)... // Mal: identificador no intuitivo

void pasoAuxiliar(double area)... // Mal: identificador sin sentido

void procesaYCuenta()... // Mal: Dividir en dos funciones


Cuando un identificador contiene una conjunción como y, es signo inequívoco de que la función que nombra realiza más de una tarea y debe ser por tanto separada en dos funciones separadas.

Los mejores identificadores son aquellos que describen con un identificador más corto lo que hace la función. Además, es interesante seguir ciertas pautas: en el caso de funciones que devuelven un booleano (un valor verdadero o falso), es interesante nombrarlos con un prefijo formado por los verbos ser o estar, como:


bool esPalindromo(char[] cadena)...

bool esPar(int x)...

bool fueModificada(double[] historialCuentaCorriente, int[] fechas)...


4Comentarios

Un comentario debe ser siempre clarificador, útil, y, en cambio, cuanto más corto mejor. En particular, debe cuidarse en no insultar la inteligencia del lector en determinadas ocasiones, comentando secuencias de código obvias y desesperarlo al encontrarse con construcciones complejas que no tienen ningún comentario.


int areaRectangulo = lado1 * lado2; // calcula área

areaCirculo = PI * r * r; // calcula área del círculo

// PI es 3.1415927


En el contexto del ejemplo anterior, el tercer comentario es absolutamente innecesario, mientras que los dos primeros son cuestionables, siempre que los identificadores hayan sido escogidos cuidadosamente, como es el caso.

Siguiendo una metáfora literaria, los comentarios a la derecha deben emplearse como mensajes aclaratorios, intentando mantener especialmente en ellos la concisión, pues es fácil que se alcancen rápidamente más de ochenta caracteres en esa línea. Agravando aún más este último problema, deben colocarse alejados del código que aclaran para que sean visibles.


// Cálculos previos al rendering

areaRectangulo = lado1 * lado2; // en cms


4.1Comentarios explicativos de funciones

Justo antes de una función, se puede y se debe crear un comentario especial que describe lo que realiza la función. El formato y los comandos de estos comentarios disponibles en jC, están basados en los de la famosa herramienta JavaDoc, que se comercializó con Java desde el comienzo de su andadura, en 1995.


/**

@brief Lista las personas en una cadena

@param buffer vector de caracteres para listado

@param vp vector de personas a listar

*/

char[] listarPersonas(char[] vectorNombresPersonas)

{

char[] toret = new char[ 0 ];


// Obtener los nombres de cada persona

for(int i = 0; i < size( vectorNombresPersonas ); ++i) {

toret = strConcat( toret, vectorNombresPersonas[ i ] );

toret = strConcat( toret, “\n” );

}


return toret;

}


Este tipo de comentario debe comenzar por /**, y así, al compilar el código, jC genera la documentación recogida en formato HTML, que lo hace ideal para las referencias cruzadas. Estos comentarios también son útiles al desnudo, por lo que su utilidad se duplica al tenerlos disponibles como un documento y también como comentarios aclaratorios en el propio código.

De los parámetros que se pueden utilizar en este tipo de comentarios, destacan @param y @return. El primero sirve para documentar un parámetro de una función o procedimiento, tal y como se ve en la función listarPersonas() del ejemplo, más arriba. El comando @brief permite documentar de forma resumida lo que realiza una función.