El formato del código es un factor a tener en cuenta a la hora de mejorar la legibilidad del mismo. Esto se consigue eligiendo un conjunto de reglas, ya sea en solitario o en equipo, y aplicándolas durante todo el proyecto.
El propósito del formato
El propósito principal del formato es hacer el código más uniforme. La legibilidad del código es fundamental tanto para el desarrollo como para el mantenimiento del mismo. Modificar un código menos legible tendrá un coste más elevado ya que los programadores tardarán más tiempo en entenderlo.Formato vertical
No hay una regla fija que describa cuantas líneas de código tiene que tener un fichero, independientemente de si es una clase u otro tipo de fichero.Según el análisis de diversos proyectos que se comenta en el Clean Code, al parecer, suele utilizarse la media se sitúa en 200 líneas de código, siendo el máximo de 500 líneas, aunque se trata más bien una directriz.
La metáfora del periódico
Un artículo de un periódico bien estructurado está formado por un título el cual transmite el tema. Con esta información el lector puede decidir si le interesa y quiere seguir profundizando. El primer párrafo es una sinopsis del artículo que dará lugar a distintos párrafos dónde se vaya añadiendo información más concreta.Los ficheros de código fuente deberían tener una estructura con el mismo patrón donde el lector pueda profundizar en datos más concretos si le interesa.
Separación vertical entre conceptos
El código está compuesto por líneas de código y cada una de ellas es una instrucción. Un concepto estará representado por varias líneas de instrucciones. Si cada concepto está agrupado y se deja una línea en blanco entre conceptos la legibilidad del código aumenta considerablemente ya que los lectores pueden identificar bloques de código que representan un mismo concepto.En el siguiente ejemplo se pueden apreciar distintos conceptos como «namespace», y «use», así como la clase y los métodos.
Si los conceptos no tuvieran esa separación entre ellos sería más difícil identificarlos. No obstante, la legibilidad del código en el siguiente ejemplo, aún tratándose del mismo que en el caso anterior, es inferior.
Densidad vertical
Si la separación vertical separa conceptos, podemos decir que la densidad vertical implica asociación.En el siguiente ejemplo los comentarios sobre los atributos de la clase rompen la asociación de conceptos obligando al lector a mirar con detenimiento para comprender que son dos atributos de la clase.
En este ejemplo el lector puede localizar de un vistazo rápido los dos atributos y el método de la clase. Mucho más legible.
Distancia vertical
Si la densidad vertical implica asociación de conceptos, podemos decir que la distancia vertical implica la relación entre dichos conceptos. Cuanto más relacionados están los conceptos más cerca deberían estar. Esta regla no se aplica a conceptos que estén en archivos separados, es decir, si los conceptos están muy relacionados no deberían estar en archivos diferentes sin una buena razón. De hecho esta es una de las razones por las que deberían evitarse variables de tipo «protected».El objetivo de esta regla es evitar que los lectores tengan que saltar entre archivos y clases para comprender el código.
Declaración de variables
Las variables deberían estar declaradas tan cerca como sea posible. Como las funciones deben ser cortas las variables locales deberían aparecer al principio de cada función.
Las variables de control de los bucles deberían declararse en la instrucción del bucle.
Podría declararse una variable dentro de un bloque o antes de un bucle si la función es inusualmente larga.
Variables de instancia
Deberían estar declaradas en la parte superior de la clase sin distancia vertical entre ellas, ya que todos o casi todos los métodos de la clase deberían utilizarlas.
Funciones dependientes
Si una función hace una llamada a otra, esta debería estar en proximidad vertical. De hecho, debería figurar inmediatamente después si fuera posible. Esta convención permite a los lectores saber que si hay una llamada a una función, esta tendrá cerca su definición.
Esto facilita encontrar la definición de las funciones que se llaman y mejora la legibilidad del código.
Afinidad conceptual
Cuanta más afinidad conceptual tengan los conceptos menos distancia tendría que haber entre ellos.
Un ejemplo de afinidad conceptual se da cuando una función "a" utilza a su vez una función "b". En este caso, la función "b" debería estar definida a continuación de la función "a". Otro ejemplo sería si esta función "b" utilizara una variable dentro de la función "a" en cuyo caso, esta variable, debería estar antes de la llamada a la función "b". Hay otros ejemplos como podría ser una agrupación de funciones que realizan operaciones similares.
En este caso las funciones crean instancias a partir de distintos parámetros de entrada.
Orden vertical
Cómo en los artículos de un periódico, la estructura del código debería tener los conceptos más importantes en la parte superior e ir encontrando el desarrollo de estos conceptos a medida que se desciende en el código hasta llegar a los detalles. Esto crea un flujo de lectura descendente.Gracias a esta estrategia, el lector puede identificar qué conceptos se están expresando de un vistazo, evitando así perder el tiempo en la comprensión de detalles superfluos.
Formato horizontal
No hay una regla escrita para la cantidad de caracteres que debería tener una línea.La directriz es que no debería ser necesario desplazarse por la pantalla en sentido horizontal. Las variables del tamaño de la pantalla y el tamaño de la letra pueden influir en el ancho de las líneas pero parece que hay una recomendación de 120 caracteres como máximo.
Amplitud y densidad horizontal
Los espacios en blanco se usan para asociar y desasociar elementos que están más o menos relacionados.En el caso de las asignaciones se usa el espacio a ambos lados del operador de asignación para acentuarlo. Además, así se consigue que los elementos de la asignación resulten obvios.
Las funciones y sus argumentos tienen una relación muy cercana, por lo que no se deberían usar espacios en blanco. La lista de argumentos va separada con un espacio en blanco después de cada argumento con el fin de mejorar la legibilidad de los mismos y saber cuántos hay de un sólo vistazo.
Otra utilidad podría ser para acentuar la precedencia de los operadores.
Alineación horizontal
Aunque inicialmente esta estrategia pueda parecer una buena idea, en la práctica no resulta útil ya que, al mirar la lista de declaraciones el lector tenderá a centrarse en la primera columna, que suele leerse entera sin consultar el nombre de la variable o su declaración.Indentación
El objetivo de la indentación es hacer visible la jerarquía de contextos del código. El fichero está compuesto por distintos contextos y cada contexto tiene asociada una determinada visibilidad. Existe un contexto global, contextos de clases, contextos funciones, contextos de bloques, etc.Para que la jerarquía de contextos sea visible, estos se indentan a medida que se engloban dentro de otros contextos. Las instrucciones que aparecen en el nivel de archivos no tienen indentación, pues se trata del primer nivel. La definición de una clase estaría en este primer nivel. Los atributos y método de esta clase tendrían un nivel de indentación respecto al contexto que los engloba que es la definición de la clase. Las implementaciones de los métodos tendrán un nivel de indentación respecto al contexto que las engloba que, en su caso, es la definición del método. Los bloques de código generados por estructuras de control como «if», «else», «switch», «for», etc. también tienen un nivel de indentación respecto al contexto en el que se definen. Si un bloque está definido dentro de otro bloque, este tendrá un nivel de indentación superior al contexto en el que se define, en su caso, el bloque que lo engloba y así se continúa.
Esta jerarquía de indentaciones permite al lector identificar de un vistazo los distintos contextos del archivo. Sin indentación los programas serían prácticamente incompresibles para un humano.
Romper la indentación
Aunque hay situaciones en las que romper la indentación pueda parecer una manera de simplificar el código al no tener varias líneas, en el fondo no lo es, ya que se rompe la estética visual y se obliga al lector a revisar esa excepción.
Así que por simple que sea la instrucción siempre es más legible continuar con la indentación aún en instrucciones simples como puede ser un mero «;».
Contextos sin utilidad
Cuando no se pueden evitar este tipo de estructuras se sigue aplicando la regla de indentar aunque sea el «;».Reglas de equipo
Un buen código es aquel que está compuesto por un conjunto de documentos que son capaces de entenderse fácilmente. Que todos los documentos tengan las mismas reglas de estilo es una parte importante para la compresión del código. Si el código incluye distintas formas de definir una clase, el lector se sentirá confuso debido a la innecesaria complejidad de la lectura.Por esta razón, los equipos de desarrollo deben elegir unas reglas de estilo y aplicarlas en todos los documentos.