Deep Nesting: Por qué y cómo evitarlo

Deep Nesting o anidación profunda. Este tipo de código se identifica muy rápido. Habitualmente podrás verlo cuando se encadenan demasiados condicionales, aunque puede pasar con cualquier otra estructura de control de flujo o incluso con métodos anidados.

¿Por qué evitarlo?

Write Code for Other People es el mantra que intento seguir siempre. Tiene que ver con esforzarse en trabajar bien entendiendo el trabajo colaborativo como algo esencial, aunque tu equipo sea pequeño, aunque trabajes solo.

Es por eso por lo que hay que intentar evitar el deep nesting, porque técnicamente es un código que puede funcionar impecable. Pero cuando alguna otra persona o incluso tu yo del futuro tenga que tocar ese código, será necesario para su salud mental y para su productividad que tu código se entienda rápido. Y cada anidación incrementa exponencialmente la dificultad de lectura y por tanto la probabilidad de error.

En resumen: dificulta la lectura. Dificulta la refactorización. Es más propenso a errores.

¿Cómo evitarlo?

Quizá hay situaciones que no puedes evitar tantas anidaciones, pero sí puedes hacerlo más claro. En PHP por ejemplo si estás mezclando if, foreach y demás, puedes usar la sintaxis alternativa. No corrige el problema, pero puede suavizarlo.

# Sintaxis tradicional

if( $cosa_1_funcionando ){
  foreach( $listado_de_cosas as $cosa ){
    print_r( $cosa );
  }
}

# Sintaxis alternativa

if( $cosa_1_funcionando ):
  foreach( $listado_de_cosas as $cosa ):
    print_r( $cosa );
  endforeach;
endif;

Ya de paso; la sintaxis alternativa también va muy bien para intercalar código HTML y PHP. Pero ese es otro tema.

La mejora principal se produce cuando se invierte la condición y se corta el flujo. Por ejemplo:

function printPosts (){

  $posts = readPostsFromDB();

  if( is_array($posts) ){
    if( count($posts) >= 1 ){
      foreach( $posts as $post ){
        echo '<article>';
        # ...
        echo '</article>';
      }
    }else{
      return false;
    }
  }else{
    return false;
  }
}

En este ejemplo hay 4 anidaciones, 3 son de estructuras de control. Invirtiendo esos if podría quedar así:

function printPosts (){

  $posts = readPostsFromDB();

  if( !is_array($posts) ) return false;
  if( count($posts) >= 1 ) return false;

  foreach( $posts as $post ){
    echo '<article>';
    # ...
    echo '</article>';
  }
}

Se han eliminado las anidaciones por estructura de control, se han eliminado unas cuantas lineas y se ha vuelto mucho más legible.

Lo mismo puede hacerse con los bucles, por ejemplo, si quisiéramos mostrar el post sólo si $post['public'] === true, no hace falta que pongamos todo el contenido del foreach dentro de ese if. Podemos poner algo como:

foreach( $posts as $post ){

  if( !$post['public'] ) continue;

  echo '<article>';
  # ...
  echo '</article>';
}

Usando el continue saltará a la siguiente iteración.

Algo parecido puede hacerse usando break, con él en lugar de saltar la iteración, saldrá de la estructura y continuará con lo que venga después. break puede usarse con for, foreach, while, do-while o switch.

Conclusión

El deep nesting no es un problema técnico, pero tiende a provocar errores humanos. Si el lenguaje lo permite puede suavizarse con la sintaxis alternativa. Habitualmente mejora invirtiendo condicionales y controlando mejor las estructuras.

Algunos enlaces de interés:

¿Quieres más? 👇
Recopilatorio de buenas prácticas para el día a día.

Comentarios (0)

No hay comentarios. Sé el primero en comentar.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.