Indentación del código fuente

3
33588

Indentación
del código fuente

  1. Indentación del
    código fuente

    1. Objetivo de la indentación
    2. Requerimientos para definir un estilo
      de indentación
    3. Un ejemplo de indentaciones
      habituales para C++ y Java
    4. Creando tu propio estilo de
      indentación
    5. Conclusión

Todos
los desarrolladores utilizan algún estilo de
colocación de los elementos del código fuente
dentro del texto que los contiene. Esto se define como el estilo de
codificación. Las normas de indentación indican
la posición en la que se deben colocar los diferentes
elementos que se incluyen en el código fuente, por lo que
forman parte del estilo de codificación. Otro ejemplo de
ello es la separación con espacios en blanco entre los
diferentes elementos que componen las líneas de
código.

Objetivo de la
indentación

El objetivo fundamental de la
indentación del código fuente es facilitar su
lectura y comprensión. Hay dos tipos de posibles lectores
del código fuente: programas y personas. A los programas les
da igual la indentación, leen bien nuestro código
siempre que cumpla la sintaxis del lenguaje. Luego la
indentación debe centrarse en la lectura y
comprensión del código por personas.

Para
entender cómo hay que indentar un código primero
hay que entender cómo lo lee una persona. Actualmente la
mayor parte de las personas que leen código fuente
lo hacen con editores de texto simples o con la ayuda de los editores
de los entornos de desarrollo. Por tanto nos vamos a centrar en este
tipo de lectores.

Cuando una persona lee
un código fuente, lo hace siguiendo una serie de patrones de
lectura. Si queremos facilitar la lectura del código lo
primero que hay que entender son estos patrones. La mejor
bibliografía sobre patrones de lectura son los libros que
enseñan sistemas de lectura rápida; dos puntos
fundamentales de estos sistemas son el estudio de los patrones de
movimiento de la vista y el reconocimiento de la estructura del texto.

Los
patrones de lectura nos indican el movimiento que siguen los ojos al
leer un texto. Cuando leemos un texto, la vista se desliza a saltos, no
se desplaza de una manera continua. Nuestra vista capta la
información y que haya alrededor del punto en que se detiene
la vista. Un buen lector hace pocas paradas para leer una
línea, aprovechando más su campo visual.

Por
otra parte, al leer también utilizamos la visión
periférica, aprovechando la estructura y
disposición que tienen las letras para extraer
información adicional del texto. Así, por ejemplo,
instintivamente nos fijamos en el principio del párrafo para
buscar la información relevante, y nos ayudamos de elementos
como las listas, los tabuladores, tablas y otros elementos
tipográficos al leer.

De estos puntos
deducimos que la posición absoluta y relativa de los
elementos que componen el texto del código fuente juegan un
papel importante a la hora de facilitar la lectura y
comprensión del mismo.

Requerimientos
para definir un estilo de indentación

Vamos
a enumerar los principales requisitos para poder definir un buen estilo
de indentación. Algunos de los más importantes
serán:

  • Que el
    posicionamiento de los elementos dentro del texto sea predecible.
    Cuanto más predecible es la posición, el
    movimiento de los ojos llega antes a los puntos relevantes del
    código fuente. El punto más relevante de
    información es siempre el principio de la línea,
    por lo que hay que tener especial atención en él.
  • Que
    la relevancia de la agrupación de los elementos refleje la
    relevancia de éstos dentro del programa.
  • Priorizar
    la identificación del flujo del programa frente al detalle
    de los elementos que lo componen. Por ejemplo es más
    importante siempre tener una visión global de lo que hace
    una función que del detalle de cómo se declaran
    sus variables.
  • Que los comentarios respeten la
    indentación de los elementos a los que van asociados,
    posicionándose de manera relativa a ellos según
    su relevancia. Si el lenguaje lo permite, hay que distinguir la
    relevancia de un comentario posicionándolo sobre el elemento
    (más importante) o al lado de él (menos
    importante). Es mejor situar los comentarios antes del elemento, ya que
    nos sirven de introducción a lo que va a
    continuación, y muchas veces nos permitirá
    saltarnos un bloque de código que no nos interesa.
  • Utilizar
    la indentación basada en tabuladores. La
    indentación basada en el uso de caracteres de espacio en
    blanco es menos flexible que la basada en tabuladores, ya que los
    editores y entornos de desarrollo modernos permiten adapatar con
    facilidad el ancho de los tabuladores al gusto de cada programador.
  • Mantener
    el tamaño de las líneas dentro de los
    márgenes de la pantalla, siempre que sea posible. Debemos
    tener en cuenta al lector potencial del código fuente. No se
    debe pensar que el lector tiene una pantalla demasiado
    pequeña o grande, sino asumir que el lector tiene una
    pantalla típica dentro del entorno de desarrollo habitual.
    Por ejemplo actualmente los desarrolladores suelen tener pantallas
    capaces de mostrar 40 líneas y 120 columnas de caracteres
    con facilidad. En este caso, utilizar el antiguo margen de 80 columnas
    por línea y 25 líneas por pantalla es
    más bien escaso.
  • Utilizar el menor
    número de normas de indentación requerido.
    Indentar elementos en exceso complica visualmente la lectura del
    código, si no son estrictamente necesarios.

Un
ejemplo de indentaciones habituales para C++ y Java

En
primer lugar vamos a examinar diferentes estilos de
indentación de una función C++ con 
algunas sentencias if,
for
y llamadas a otras funciones.

void
foo(int
entrada)

{

    
int i=0;

    
if(i===0)

    
{

             
int result = obtener_resultado(“clase”,


                                          
 “tipo”,

                                          
“valor”);

             
for(int j=1;j<10;++j)

             
{

                  
string s = cargar(“dato inicial”,


                                 
    “dato final”,


                                 
    Trae

                                 
    CARGAR_DE_BD);

                  
cout << “j vale” << j
<< endl;

             
}

    
} else

    
{

 

             
Cout << “no entró”
<< endl;

    
}

}

Este
estilo está muy extendido entre los programadores, y es el
obligatorio para muchos proyectos. Analicemos un poco su estructura.
Para ello vamos a resaltar algunos elementos.

void
foo(int entrada)

{

    
|int
i=0;

    
|if(i===0)


    
|{


             
|int
result = obtener_resultado(“clase”,


                                          
 “tipo”,


                                          
“valor”);


             
for(int j=1;j<10;++j)

             
|{


                  
|string
s = cargar(“dato
inicial”,

                                 
    “dato
final”,

                                 
    Trae


                                 
    CARGAR_DE_BD);


                  
|cout
<< “j vale” << j
<< endl;

             
|}


    
|}
else

    
|{


 

             
|cout
<< “no entró”
<< endl;

    
|}


}

He
introducido símbolos ‘|’  para que se vean los
diferentes niveles de indentación. Además he
resaltado en amarillo el texto que corresponde a la lista de
parámetros pasados las funciones. Veamos qué
requisitos no cumple. En primer lugar, la vista debe
dar muchos saltos innecesarios. La vista va a saltar al menos a los
elementos remarcados. Además algunos de los saltos no siguen
un patrón definido, ya que las distancias entre saltos
varían para el mismo tipo de sentencia.

Mejoremos
este ejemplo un poco. Lo primero es reorganizar las llamadas a
función, ya que son menos importantes que la estructura del
flujo de la función.

void
foo(int entrada)

{

     
|int
i=0;

     
|if(i===0)


     
|{


                 
|int
result = obtener_resultado(“clase”, 
“tipo”,


                       
      valor”);


                 
for(int j=1;j<10;++j)

                 
|{


                       
|string
s = cargar(“dato
inicial”,

                                   
“dato
final”,
Trae
CARGAR_DE_BD);


                       
|cout
<< “j vale” << j
<< endl;

                 
|}


     
|}
else

     
|{


 

                 
|cout
<< “no entró”
<< endl;

     
|}


}

Los
parámetros de la función no son ahora tan
visibles. La vista ya no va directamente a ellos al intentar seguir el
flujo, tenemos que detenernos en ellos a propósito.

Ahora
modificamos las llaves de apertura y corregimos el tamaño de
los indentados: un tabulador para un nivel interior y dos tabuladores
para escribir la parte de una sentencia que no nos cabe en una
línea.

void
foo(int entrada)

{

     
|int
i=0;

     
|if(i===0)


     
|{


           
|int
result = obtener_resultado(“clase”, 
“tipo”,


                 
      valor”);


           
for(int j=1;j<10;++j) {

                 
|string
s = cargar(“dato
inicial”,

                             
“dato
final”,
Trae
CARGAR_DE_BD);


                 
|cout
<< “j vale” << j
<< endl;

           
|}


     
|}
else {

 

           
|cout
<< “no entró”
<< endl;

     
|}


}

Como vemos
la
vista sigue ahora un
patrón predecible. Pero todavía lo podemos
mejorar más. Vamos a colocar las llaves de cierre en una
posición poco usual. Las vamos a poner a la misma altura que
las sentencias que engloban. Veréis el resultado.

void
foo(int entrada)

{

     
|int
i=0;

     
|if(i===0)


     
|{


           
|int
result = obtener_resultado(“clase”, 
“tipo”,


                 
      valor”);


           
for(int j=1;j<10;++j) {

                 
|string
s = cargar(“dato
inicial”,

                             
“dato
final”,
Trae
CARGAR_DE_BD);


                 
|cout
<< “j vale” << j
<< endl;

           
      |}


     
      |}

     
|else
{

 

           
|cout
<< “no entró”
<< endl;

     
      |}


}

Como
vemos, las llaves de cierre forman columna con la sentencias a las que
pertenecen. Si añadimos algunas sentencias más lo
apreciareis mejor:

void
foo(int entrada)

{

     
|int
i=0;

     
|if(i===0)


     
|{


           
|int
result = obtener_resultado(“clase”, 
“tipo”,


                 
      valor”);


           
for(int j=1;j<10;++j) {

                 
|string
s = cargar(“dato
inicial”,

                             
“dato
final”,
Trae
CARGAR_DE_BD);


                 
|cout
<< “j vale” << j
<< endl;

           
      |}


           
|llamadaAotraFuncion(parametro1,
parametro2);

           
|cout
<< “otra funcion llamada”
<< endl;

     
      |}

     
|else

 

           
|cout
<< “no entró”
<< endl;

}
 

Además
en el
último else
he quitado las llaves, que no son necesarias. A los puristas les gusta
tener puestas las llaves, por si hay que añadir
código. Los más perezosos 
(¿inteligentes?) las ponemos sólo si hacen falta.
Entonces te dirán: ¿y si el programador pone una
llave de apertura y no la cierra? ¿Y cómo sabes
si te falta alguna llave? Aquí hay varias respuestas.
Primero, si el programador se olvida de llaves lo va a hacer le digas
lo que le digas… Además no es bueno ponerse la
venda antes de tener la herida. En segundo lugar, todos los
compiladores te indican si hay llaves de más o de menos. Si
el asunto es una llave mal colocada es fácil buscarla. En
primer lugar si ves una llave de apertura rápidamente puedes
buscar la de cierre. En el ejemplo vemos que es muy fácil
ver que el último cout lleva la llave de cierre del if
al que pertenece.

Veamos el texto sin resaltados.

void
foo(int entrada)

{

     
int i=0;

     
if (i===0)

     
{

           
int result =
obtener_resultado(“clase”,  
“tipo”,

                       
valor”);

           
for (int j=1;j<10;++j) {

                 
string s = cargar(“dato inicial”,


                             
“dato final”, Trae,  CARGAR_DE_BD);


                 
cout << “j vale” << j
<< endl;

           
      }


           
llamadaAotraFuncion(parametro1, parametro2);

           
cout << “otra funcion llamada”
<< endl;

     
      }


     
else

           
cout << “no entró”
<< endl;

} 

Como
veis el código cumple todos los requisitos que hemos
enumerado al principio. Es muy legible y la vista
rápidamente identifica la estructura y flujo de la
aplicación. Las llaves están colocadas de manera
que no entorpecen pero se ven suficientemente (no hace falta esconderlas
más), y los parámetros de las funciones no
están tan destacados.

Comparemos ambos
estilos de codificación.  

void
foo(int entrada)

{

         
int i=0;

         
if(i===0)

         
{

                            
int result = obtener_resultado(“clase”,


                                                                            
         
 “tipo”,

                                                                            
         
“valor”);

                            
for(int j=1;j<10;++j)

                            
{

                                     
string s = cargar(“dato inicial”,


                                                                  
    “dato final”,


                                                                  
    Trae

                                                                  
    CARGAR_DE_BD);

                                     
cout << “j vale” << j
<< endl;

                            
}

         
} else

         
{

                            
Cout << “no entró”
<< endl;

         
}

}
void
foo(int entrada)

{

         
int i=0;

         
if (i===0)

         
{

                  
int result =
obtener_resultado(“clase”,        
“tipo”,

                                     
valor”);

                  
for (int j=1;j<10;++j) {

                            
string s = cargar(“dato inicial”,


                                               
“dato final”, Trae,  CARGAR_DE_BD);


                            
cout << “j vale” << j
<< endl;

                            
}

                  
llamadaAotraFuncion(parametro1, parametro2);

                  
cout << “otra funcion llamada”
<< endl;

                  
}

         
else

                  
cout << “no entró”
<< endl;


Y
ahora llegan las votaciones. ¿Con cuál te
identificas más? ¿Cuál te gusta
más?

Creando tu propio estilo de
indentación

Con lo que hemos aprendido
hasta ahora podremos definir nuestro propio estilo de
indentación, que podremos usar siempre que no nos impongan
ya uno. Debemos fijarnos siempre en qué
información debe presentar el código fuente,
cómo debe remarcar la relevancia de cada parte y
cómo debe guiar a la vista del futuro lector por las partes
más importantes de nuestro programa.

Conclusión

En
este artículo hemos revisado los criterios que usamos
habitualmente para indentar los textos de los códigos
fuentes. También propongo una serie de requisitos sencillos
para definir nuestros propios estilos de indentación.

Podéis
enviarme correo con vuestras críticas y opiniones, pues de
antemano me gustará conocer vuestra opinión, que
no tiene porqué coincidir con la mía.

3 Comentarios

  1. Hola Cristóbal me gusto mucho tú artículo y uno de las razones principales es para que como bien dices el lector a futuro del código fuente intérprete con mucha facilidad el conjunto de líneas de sentencias. De mi parte iré utilizando tu modelo, para posteriormente encontrar mi propia personalización. De antemano gracias.

Dejar respuesta

Please enter your comment!
Please enter your name here