Documentación Upnify!®

Sección Inducción Código Limpio

¿Qué es código limpio?

Definiciones tomadas del libro "Código limpio".

Bjarne Stroustrup, creador de C++.

"Me gusta que mi código sea elegante y eficaz. La lógica debe ser directa para evitar errores ocultos, las dependencias deben de ser mí­nimas para facilitar el mantenimiento… El código limpio hace bien una cosa."

Dave Thomas, fundador de OTI.

"El código limpio se puede leer y mejorar por parte de un programador que no sea su autor original. Tiene pruebas de unidad y de aceptación. Tiene nombres con sentido. Ofrece una y no varias formas de hacer algo."

Michael Feathers, autor de Working Effectively with Legacy Code.

"El código limpio siempre parece que ha sido escrito por alguien a quien le importa. No hay nada evidente que hacer para mejorarlo."

Para crear un código limpio se requiere de mucho esfuerzo, conocimiento, trabajo constante, y no siempre se consigue a la primera. Es por eso que cada lí­nea de código escrita, se debe analizar, sintetizar y volver a reescribir si es necesario para que cumpla con las caracterí­sticas mencionadas anteriormente.

"Y es que todo el código en cualquier proyecto deberí­a verse como si una sola persona lo hubiera escrito, sin importar cuánta gente haya contribuido."

La regla del Boy Scout

Hay una regla simple y directa para los Boy Scouts definida por Lord Robert Stephenson Smith Baden-Powell. "Intenta dejar este mundo un poco mejor de como lo encontraste."

Sin embargo, Uncle Bob, autor del libro código limpio, lo toma de otra manera. "Siempre deja el lugar del campamento más limpio que como lo encontraste."

Si abres un archivo para revisarlo y ves que no está cumpliendo algunos requisitos, no importa quién fue el autor original, toma un poco de tu tiempo y la molestia de mejorarlo; agregando o borrando comentarios, renombrando variables o funciones, formateando el código, etc.

"Deja el código mejor de cómo lo encontraste."

No estoy diciendo que se haga una refactorización completa del código, más bien simples mejoras que pueden contribuir a que el código sea aún mejor para mantenerlo y que no se degrade, es decir que mejore en muchos aspectos (lectura, testeable, etc). Sigue la regla del Boy Scout, no seas individualista cuidando todos los detalles solo de tu desarrollo, ayuda a aquellos que están escribiendo mal y en concreto, a que mejoren.

Espacios en blanco e Indentación

Normalmente se puede trabajar con indentación y espacios en blanco en el código y no es importante para el intérprete puesto que no los toma en cuenta, pero para el programador, esto proveé una mejor legibilidad del código.

Entonces la recomendación es que:

  • Nunca se debe mezclar espacios y tabulaciones.
  • De preferencia, se debe indentar con 4 espacios.
  • No uses tabulaciones

Longitud de una lí­nea

El lí­mite de las lí­neas de código deberán ser de 80 a 90 caracteres, esto ayudará a una mejor lectura del código.

Comillas

Como recomendación, utiliza comillas simples como delimitadores externos. Solo si estás escribiendo JSON, utiliza comillas dobles, en los demás casos usa comillas simples.

Recomendado

              const foo = 'bar';
              console.log('bar');
              function(foo,bar){
                const x = 'hi' + foo + ';' + 'bar'
              }
            

Llaves

La llave de apertura deberá ir en la misma lí­nea de la sentencia. Si colocas en la siguiente lí­nea, en algunos casos muy particulares se puede producir algún error. Más adelante se explica dicho error en el uso de punto y coma en las sentencias.

No recomendado

                  //control flow stament
                  if (true)
                  {
                    //codes goes here
                  }
                  //Anonymus function declaration
                  function (args)
                  {
                    return true;
                  }
                  //Named function declaration
                  function foo ()
                  {
                    return true;
                  }
                  //Anonymus function expression
                  const bar = function (args)
                  {
                    return true;
                  }
                  //Arrow function
                  const bar =  (args)=>
                  {
                    return true;
                  };
                  const bar = (args)=>
                  {true}
                
Recomendado

                  //control flow stament
                  if (true) {
                    //codes goes here
                  }

                  //Anonymus function declaration
                  function (args) {
                    return true;
                  }

                  //Named function declaration
                  function foo () {
                    return true;
                  }

                  //Anonymus function expression
                  const bar = function (args) {
                    return true;
                  }

                  //Arrow function
                  const bar =  (args)=> {return true,
                  };
                  const bar = (args)=> {true};
                  const bar = (args)=> true;


                

Punto y coma

Javascript utiliza ASI (Automatic Semicolon Insertion) cuando se trata de insertar un “punto y coma” que ha sido omitido en cada instrucción, y que es separada en una lí­nea diferente. Técnicamente es posible, sin embargo esta no es una buena práctica, porque en ciertas ocasiones se puede generar un error que será un quebradero de cabeza poder solucionarlo.

Veamos un ejemplo.

La función getName únicamente nos devolverá una estructura de datos sencilla.


              console.log(getName);

              function getName(){
                return
                {
                  name: '@fulanito'
                }
              }
            
  • Al ejecutar el código se obtendrá el resultado: undefined
  • Sin embargo, se esperaba como resultado: { name: '@davidenq' }

El error se encuentra después de return porque la llave de apertura deberí­a colocarse a continuación, y no en la siguiente lí­nea.


              //Esto es lo que se interpreta
              function getName(){
                return; //Error
                {
                  name: "Bootcampio"
                };
              }
            

Para evitar este tipo de problemas es importante adoptar de manera estricta la convención de apertura de llaves y procurar finalizar una instrucción con un punto y coma cuando sea necesario.

¿Dónde usar punto y coma en las instrucciones?

Cuando se trata de algunos flujos de control


              //Control flow stament
              do {
                //code goes here
              } while (codition); //Necessary semicolon
            

Cuando se trata de expresiones de funciones o funciones flecha


              //Anonymous function expression
              const bar = function (args) {
                //code goes here
              };

              //Named function expression
              const bar = function foo (args) {
                //code goes here
              }

              //Autoload function
              (function(args){
                //Code goes here
              })(args);

              //Arrow function
              const bar = () => {
                return foo;
              };

              const bar = () => {foo};

              const bar = () => foo;
            

Después de declarar objetos, arreglos, returns (Cuando se retorna una expresión o resultado)

Objetos

              const params = {
                'a':1,
                'b':2,
                'c':'string'
              };
            
Arreglos

              const fruits = ['apple', 'orange', 'Pear'];
            
Returns

              ...
              return {...};
              ...

              ...
              return (...);
              ...

              ...
              return expression;
              ...
            

¿Dónde se puede omitir el punto y coma en las instrucciones?

En condiciones o ciclos

              if( condition ) {
                //codes goes here
              } else if (otherCondition ){
                //other codes goes here
              } else {
                //other codes goes here
              }
              for( operation ) {
                //codes goes here
              }
              while( condition ) {
                //codes goes here
              }
            
En funciones declaradas

              //Anonymous function declaration
              function ( args ){
                //codes goes here
              }
              //Named function declaration
              function foo( args ){
                //codes goes here
              }
            

Declaración de variables

La recomendación es usar const y let en lugar de var.

La declaración de las variables será en la parte superior de su ámbito aunque Javascript no requiera esto. Tratando de que su ámbito sea local y no global. El resultado de esto nos brinda:

  • Código limpio
  • Proporciona un único punto de búsqueda de las variables que son utilizadas en un ámbito.
  • Ayuda a conocer que variables están involucradas en el ámbito contenedor.

Formato de declaración

No recomendado

                  const day = 1;
                  const count = 10;
                  const keys = [‘foo’, ‘bar’];
                  const values = [1, 2];




                
Recomendado

                  // separar por comas
                  const day = ‘Monday’,
                  count = 10;
                  //Alinear
                  const day   = ‘Monday’,
                  count = 10;
                  //En la misma lí­nea
                  const day = ‘Monday’, count = 10;
                

Comparaciones

Utiliza siempre la comparación estricta de valor y tipo de dato, con el operador según corresponda === or !==

Los resultados de la comparación pueden variar si no se tiene cuidado.

const x = 10;

OperadorDescripciónComparaciónResultado
==Valor igualx ==10true
==Valor igualx == 15false
==Valor igualx == "10"true
===Valor y tipo igualx === 10true
===Valor y tipo igualx === 15false
===Valor y tipo igualx === "10"false

Formato de nombres de variables y funciones

Extraído de la guí­a de estilo de Google Closure Library.

Utiliza camelCase para nombrar funciones, declaración de variables, instancias, etc.

Ejemplo


              funcionNombre;
              variableNombre;
              metodoNombre;
            

Utiliza PascalCase para nombrar constructores, prototypes, clases, etc.

Ejemplo


              ConstructorDeNombres;
              EnumeraNombres;
            

En variables

Para declarar valores constantes utiliza mayúsculas y separadas individualmente por un guión bajo cada palabra.

Recomendado

              const SYMBOLIC_CONSTANTS_LIKE_THIS;
            

Para declarar valores variables utiliza camelCase

Recomendado

              const adminUser;
              const daysSinceCreation;
            

En funciones

Para declarar funciones utiliza camelCase

Recomendado

              function userInformation;
              let doHttpCall = function(){ }
            
Nota: Las variables y funciones que se declaren deberán de ser nombradas en inglés.

Nombres con sentido

La intención de asignar un nombre con sentido a carpetas, archivos, variables, funciones, etc. es indicar cuál es su cometido, de tal manera que quede claro el propósito por el cual fue creado.

Y es que esta tarea se realiza constantemente, y toma su tiempo porque muchas de las veces cuesta mucho saber qué nombre se le puede asignar para indicar de forma directa su intención y cometido. Pero también tiene sus beneficios asignar nombres coherentes, puesto que más adelante será menor el esfuerzo cuando se vuelva a leer el código pues facilita su compresión.

Ejemplo

              const d; // Tiempo transcurrido
              const dia; // Tiempo transcurrido
            

Las variables 'd' o 'dia' no refleja absolutamente nada, puesto que no sabemos cuál es la intención de querer saber los dí­as transcurridos.

Una mejor opción sería: (extraído del libro "Código limpio")


              const diasDesdeLaCreacion;
              let diasDesdeLaModificacion;
            
Nota: ¡No declares variables pensando que se da por sentado que es claro su cometido e importancia!.

Nombres de carpetas y archivos

Utiliza camelCase para nombrar las carpetas, al tener más de dos palabras deberá separarse por punto

Recomendado

              app.ts
              app.upnify.ts
            

Comentarios

Procura asignar comentarios solo cuando sea necesario y que ayuden a entender mejor el código.

No recomendado

              /*
              * Te devuelve el día del mes actual
              * @return: día del mes
              *
              * /
              function getDayOfMonth(){
                ...
              }
            

Es claro que muchas de las declaraciones son obvias. Sin embargo, es lo que se suele encontrar en el código. No olvides que declarar nombres con sentido ayudan a la legibilidad del código y por ende, a evitar comentarios innecesarios.

Recomendado

              function getDayOfMonth(){
                ...
              }
            

Procura asignar un nombre con sentido que refleje el cometido, así­ se evitará realizar comentarios que a veces son redundantes e innecesarios.

Conclusión

Seguir las buenas prácticas de desarrollo son necesarias para evitar horas innecesarias en re-escribir un código mal escrito, llevando con ello la reducción de la productividad de trabajo.

Varios ejemplos y definiciones son tomados de algunas referencias bibliográficas. En cada uno de ellos se hace referencia a dicho enlace. Otros posiblemente no contengan el enlace porque simplemente son ejemplos propios, sin embargo, esta documentación estará en constante revisión y se agregarán las referencias en caso de ser necesario.

Referencias bibliográficas

Enlaces web

Libros

  • Douglas Crockford, Javascript: The Good Parts. Copyright 2008 Yahoo! Inc.
  • Robert C. Martin, Código Limpio — Manual de estilo para el desarrollador ágil de software. Prentice Hall, Copyright @2009

General

  • Las funciones y variables privadas comienzan con minúscula y se escriben en formato “camelCase”.
  • Las funciones, variables y propiedades públicas comienzan con mayúscula y se escriben igual en formato “PascalCase”.
  • Las constantes se escriben usando todas las letras en mayúscula y separando palabras con “guión bajo”. Ej.: MI_CONSTANTE.
  • Hacer declaraciones explícitas de las variables locales.
  • Evitar el uso de variables globales.
  • Inicializa las variables que declara.
  • Evitar el uso de guión bajo o guiones en los nombres de funciones o variables.
  • Como convención de nombramiento, use verbos para las funciones y sustantivos para las propiedades.
  • Indentar el código (4 espacios).
  • Mantener las líneas de código de una longitud de 80 a 90 caracteres.
  • No dejar código comentado.

JavaScript

  • Nunca declarar objetos de tipo Number, String or Boolean.
  • No usar “new Object()“. Usa var x = {} en su lugar.
  • Use === en vez de == siempre que se pueda.
  • Termine los “switch” con “defaults“.
  • Nunca usar eval().
  • Usar nombres de variable significativos como cuenta o valorPrevio en lugar de c or vp.
  • No dejar sentencias de tipo “debugging” tales como console.log en el código del ambiente productivo.
  • Agregar los punto y comas.
  • La declaración de variables deberá ser en la parte superior de su ámbito
  • Documentar las funciones con la estructura de jsDoc.