leanmind logo leanmind text logo

Blog

BDD

Behaviour-driven Development es una técnica para tomar mejores requisitos de producto.

Code Smells Series. Capítulo 1: Comentarios y código duplicado

Por María Guerra Suárez

Este es el primer capítulo de lo que he llamado Code Smell Series: un conjunto de artículos que recopilan los distintos tipos de “malos olores” que podemos encontrar en nuestro código, así como el por qué ocurren, cómo detectarlos y cómo mejorarlos.

En este capítulo veremos dos tipos muy comunes de code smell que pertenecen a la categoría Dispensables: los comentarios y el código duplicado.

Comentarios

code_smell_comments

Detección: Se observa fácilmente en un método o función que está lleno de comentarios explicativos. Es bastante común añadir comentarios para explicar un código que es poco intuitivo o requiere mucha carga cognitiva. Sin embargo, estos comentarios, aunque escritos con buena intención, sólo sirven para enmascarar “malos olores” que podrían ser mejorados. Los comentarios deben aparecer para explicar por qué se hace cierta lógica y no para explicar qué es lo que hace el código.

Solución: Lo mejor que podemos hacer en estos casos es revisar el código al que hace referencia el comentario y mejorarlo, por ejemplo, extrayendo el trozo de código y eligiendo un buen nombre de método, clase o variables (dependiendo de la extracción). De esta manera, el comentario será innecesario, pues el código es lo suficientemente claro como para leerse.

A continuación, muestro un ejemplo de un método con muchos comentarios:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 * This function returns the words in a list that are anagrams of another word.
 *
 * @param word
 * @param wordList
 * @returns {*[]}
 */
const anagrams = (word, wordList) => {
    let anagramList = []

    // sort the characters of the word passed by parameter
    const word1 = word.split('').sort().join('');

    // loop through the word list
    for (const w of wordList) {
        // sort the word characters
        const word2 = w.split('').sort().join('');

        // check if both words are equal
        if(word1 === word2) {
            anagramList.push(w)
        }
    }

    return anagramList;
}

En este siguiente ejemplo podemos ver como, aplicando unas cuantas extracciones y mejorando el nombre de las variables, obtenemos un código más legible sin necesidad de llenarlo de comentarios.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const anagrams = (word, wordList) => {
    let anagramList = []
    const sortedWord1Characters = sortCharacters(word);
    for (const w of wordList) {
        const sortedWord2Characters = sortCharacters(w);
        if(areCharacterEquals(sortedWord1Characters, sortedWord2Characters)) {
            anagramList.push(w)
        }
    }
    return anagramList;
}

const areCharacterEquals = (sortedWord1Characters, sortedWord2Characters) => {
    if(sortedWord1Characters.length !== sortedWord2Characters.length) return false;
    return sortedWord1Characters.every((character,index)=> character === sortedWord2Characters[index]);
}

const sortCharacters = (word) => {
    return word.split('').sort();
}

Código duplicado

code_smell_duplicate_code

Detección: Como su nombre indica, se trata de trozos de código que son o parecen idénticos. Esto es bastante común en proyectos donde trabajan varios programadores, donde es posible que uno de ellos necesite cierta funcionalidad que desconoce que ya ha sido implementada por un compañero y la vuelve a implementar. O sabe que esa lógica es usada en alguna parte de código y la copia.

Solución: Si encontramos el mismo código en varias partes del proyecto, se puede extraer en un método y y sustituir el código repetido por llamadas a ese nuevo método.

El siguiente ejemplo nos muestra unas funciones que parecen muy similares entre ellas:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function squarePerimeter(sideLength){
    return 4  *  sideLength;
}

function equilateralTrianglePerimeter(sideLength){
    return 3  *  sideLength;
}

function pentagonPerimeter(sideLength){
    return 5  *  sideLength;
}

Aquí vemos como podemos simplificar todas esas funciones en una sola :

1
2
3
function perimeterOfRegularPolygon(numberOfSides, sideLength){
    return numberOfSides  *  sideLength;
}

Siempre es ideal apoyarse en el IDE para hacer este tipo de refactor. Si usamos algún producto de JetBrains, estos son los atajos de teclado que podemos usar:

Shift + F6 (igual para Mac) → Renombrar una variable

Ctrl + Alt + M (⌥ + ⌘ + M para Mac) → Extraer método

¿Te has encontrado alguna vez con estos tipos de code smell? Si es así, espero que este capítulo te haya ayudado a obtener unas buenas prácticas para refactorizar tu código y conseguir que sea más limpio y legible.

Referencias:

Clean Code - Robert C. Martin Refactorig Guru

Publicado el 19/02/2023 por
María image

María Guerra Suárez

¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.

Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?

Impulsamos el crecimiento profesional de tu equipo de developers