Cohesión
Getting your Trinity Audio player ready...

Un poco de historia.

Ya hemos hablado del Principio de Responsabilidad Única, y no, no es una idea original de Robert C. Martin, sino que este principio parte del concepto de "cohesión". Es más, el Principio de Inversión de Dependencias, tampoco es algo original y lo que nos habla es de "acoplamiento".

Las primeras personas que hablaron de estos dos conceptos, fueron Wayne P. Stevens, Glenford Myers y Larry Constantine en su artículo "Structured Design" publicado en 1968 en la revista IBM Systems Journal. Más tarde, en 1978, Tom DeMarco, en su libro "Structured Analysis and System Specification", también describió la importancia de la cohesión como un factor clave para la calidad del software.

Por lo que a lo largo de este artículo veremos que los conceptos de acoplamiento y cohesión, son la base y el origen de otros principios y patrones que ya conocemos.

¿Qué es la cohesión?

La cohesión se refiere a la medida en que los elementos de un módulo1 están relacionados y trabajan juntos para cumplir una única función. Por lo tanto, podemos pensar en ella como un rompecabezas: cuanto mejor encajen las piezas, más alta será la cohesión.

¿Y qué significa esto? Pues ya que la cohesión nos dice cómo están relacionadas las diferentes partes de un módulo. Si las partes trabajan juntas de manera efectiva para cumplir una tarea específica, se dice que el sistema tiene alta cohesión. Pero si las partes no están bien conectadas o si cada parte hace muchas cosas diferentes, el sistema tendrá baja cohesión.

Y como un ejemplo en código vale más que mil palabras. Comencemos con esta clase, en la que dejaremos los métodos vacíos porque lo importante es el nombre de éstos:

class Library {
  public lendBook(book: Book, client: Client) { }
  public returnBook(book: Book, client: Client) { }

  public searchBookByAuthor(author: string) { }
  public searchBookByTitle(title: string) { }

  public addClient(client: Client) { }
  public deleteClient(client: Client) { }
}

Se puede ver que la clase Library hace demasiadas cosas. Si la introducimos en un módulo para gestión de bibliotecas, básicamente hará todo el trabajo ella. Y cualquier en cualquier tipo de gestión de la biblioteca, implicará un cambio en la propia clase. Para poder aumentar la cohesión del módulo necesitamos separar responsabilidades, para que haya distintas clases cada una con la suya, pero puedan trabajar en conjunto para conseguir el objetivo de gestionar una biblioteca.

class LibraryClientsList {
  public addClient(client: Client) { }
  public deleteCliente(client: Client) { }
}

class BookLoan {
  public lendBook() { }
  public returnBook() { }
}

class BookSearch {
  public searchByAuthor(autor: string) { }
  public searchByTitle(titulo: string) { }
}

Como habéis podido ver tras el ejemplo en código... ¿esto no os suena del Principio de Responsabilidad Única? Efectivamente, en otras palabras, el principio nos dice que necesitamos tener una alta cohesión.

¿Y el acoplamiento?

Con acoplamiento nos referimos a la forma de definir cómo están conectadas las diferentes partes de un sistema. Si dos módulos están altamente acoplados, significa que están muy interconectados y que cualquier cambio en uno de ellos puede afectar el funcionamiento del otro. Por otro lado, si dos módulos tienen un bajo acoplamiento, significa que están menos interconectados y que los cambios en uno de ellos no afectarán al otro.

De forma que, lo ideal es que los módulos tengan un bajo acoplamiento, ya que al minimizar las conexiones entre módulos también se reducen los caminos por lo que se pueden propagar los cambios y los errores a otras partes del sistema. De este modo, se elimina el efecto de que un cambio en un módulo pueda causar errores en otro, así evitando realizar modificaciones adicionales para solventarlo.

De todas formas, voy a poner un ejemplo para simplificarlo. En este caso, vamos a dos funciones que hacen los mismo (calcular el área de un cuadrado), pero tienen dos niveles de acoplamiento distinto.

// Función con alto acoplamiento
function calculateSquareArea(input: HTMLInputElement): number {
  const side: number = parseInt(input.value);
  return side * side;
}

// Función con bajo acoplamiento
function calculateSquareArea(side: number): number {
  return side * side;
}

La primera función depende de recibir un input HTML del que se va a leer el valor del lado del cuadrado, para posteriormente devolver el área calculada. Si cambiamos el método de entrada, no nos quedará otra que modificar la función. Así que esta función representa un alto acoplamiento. Sin embargo, en la segunda función, no importa como se haya obtenido el dato que representa el lado del cuadrado, es por ello que presenta un bajo acoplamiento.

Resumiendo, cuando hay un alto acoplamiento, es la señal de que debemos abstraer de la existencia de otros módulos en la medida de lo posible. Y como comentamos en el primer párrafo de este artículo, ¿esto a que os suena? Efectivamente, al Principio de Inversión de Dependencias.

Bajo acoplamiento, alta cohesión.

El acoplamiento y la cohesión, son dos conceptos muy importantes y estrechamente relacionados. Ya que como vimos en los apartados anteriores, si los módulos de nuestro programa están altamente acoplados, significa que cualquier cambio en uno de ellos puede afectar a los demás y hacer que el código sea difícil de entender y mantener. Por otro lado, si los módulos tienen alta cohesión, significa que están altamente relacionados entre sí y que trabajan juntos para lograr una tarea específica.

Por lo tanto, el objetivo es tener un código con alta cohesión y bajo acoplamiento. Esto hace que el código sea fácil de entender, modificar y mantener, lo que conduce a un software de mayor calidad y eficiencia. Es como tener un equipo de trabajo bien coordinado, donde cada miembro sabe exactamente lo que tiene que hacer y trabaja en armonía con los demás para conseguir un objetivo común.

En resumen, podemos decir que el acoplamiento y la cohesión son dos caras de la misma moneda en la programación. Una buena gestión de ambos conceptos puede llevar a un código limpio, fácil de entender y mantener. Así que ya sabes, ¡reduce el acoplamiento y aumenta la cohesión para subir un nivel en el mundo de la programación! (con pareado de regalo).

Espero que esta primera parte os haya servido para comprender los conceptos. En la segunda parte, veremos más en detalle cada una de ellas, centrándonos en los tipos de acoplamiento y cohesión existentes, incluyendo ejemplos de cada tipo.


  1. Con el término módulo nos estamos refiriendo a una parte de código con nombre que puede ser llamada desde otra parte y, preferentemente tiene su propio conjunto de variables 

Comparte este artículo con quien quieras
Caso práctico TDD
Hablemos de acoplamiento y cohesión. Parte 2. Cohesión

Discussion

  • Commenter's Avatar
    Scipion — 8 noviembre, 2023 at 13:00

    Hola, genial el articulo.
    Una pequeña correción. El campo “value” de un HTMLInputElement siempre devuelve string (desafortunadamente :S ) incluso si el type=”number”.
    Habrá Cohesion parte 3 ???

    • Commenter's Avatar
      jose — 8 noviembre, 2023 at 22:37

      Buenas,

      muchas gracias por la corrección, tienes toda la razón, así que actualizo el código para que represente algo más real 😉

      Y la parte 3 está en proceso, pero aún no me convence del todo jejeje.

      Saludos

Leave a Comment

Your email address will not be published. Required fields are marked *

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