¿Qué es alta cohesión y cómo usarla / fabricarla?


84

Estoy aprendiendo programación de computadoras y en varios lugares me he topado con el concepto de cohesión y entiendo que es deseable que un software tenga "alta cohesión", pero ¿qué significa? Soy un programador de Java, C y Python aprendiendo C ++ del libro C ++ Primer que menciona la cohesión sin tenerla en el índice, ¿podría indicarme algunos enlaces sobre este tema? No encontré informativa la página de wikipedia sobre la cohesión informática, ya que solo dice que es una medida cualitativa y no da ejemplos de código real.



3
Alta cohesión: comportamiento relacionado con sentarse juntos y comportamiento no relacionado con sentarse en otro lugar.
Teoman shipahi

Respuestas:


240

La alta cohesión es cuando tienes una clase que hace un trabajo bien definido. La cohesión baja es cuando una clase hace muchos trabajos que no tienen mucho en común.

Tomemos este ejemplo:

Tiene una clase que suma dos números, pero la misma clase crea una ventana que muestra el resultado. Esta es una clase de cohesión baja porque la ventana y la operación de adición no tienen mucho en común. La ventana es la parte visual del programa y la función de agregar es la lógica detrás de ella.

Para crear una solución altamente cohesiva, tendría que crear una clase Window y una clase Sum. La ventana llamará al método de Sum para obtener el resultado y mostrarlo. De esta forma desarrollarás por separado la lógica y la GUI de tu aplicación.


14
Honestamente, no defino Cohesión así. Su definición es SRP (principio de responsabilidad única). Y la cohesión se trata de si las clases en órbita de la misma característica en cuanto a paquetes están cerca unas de otras o no.
v.oddou

4
El SRP (Principio de Responsabilidad Única) es solo otra forma de expresar el mismo concepto. La cohesión es más una métrica; el SRP es una pauta pragmática que si se sigue conducirá a clases cohesionadas.
ComDubh

3
Creo que la ventana de la clase no debería llamar a ningún objeto de la suma de la clase, ya que su único propósito es representarlo, no necesita saber sobre la "existencia" de la suma de la clase o cualquier otra clase. Debería haber otra clase que diga Driver que debería obtener el resultado de la clase de suma y pasaría el resultado a la ventana de la clase para renderizar
Eklavyaa

1
No lo entiendo. Esto no es cohesión según el código limpio del tío Bob. Esto es SRP
karlihnos

¡Explicación muy clara! Gracias
Vincent Llauderes

55

Una explicación de qué es del Código completo de Steve McConnell :

La cohesión se refiere a qué tan cerca todas las rutinas de una clase o todo el código de una rutina apoyan un propósito central . Se describe que las clases que contienen una funcionalidad fuertemente relacionada tienen una fuerte cohesión, y el objetivo heurístico es hacer que la cohesión sea lo más fuerte posible. La cohesión es una herramienta útil para administrar la complejidad porque cuanto más código en una clase respalda un propósito central, más fácilmente su cerebro puede recordar todo lo que hace el código.

Alguna forma de lograrlo desde el Código Limpio del tío Bob :

Las clases deben tener una pequeña cantidad de variables de instancia . Cada uno de los métodos de una clase debe manipular una o más de esas variables. En general, cuantas más variables manipula un método, más cohesivo es ese método con su clase. Una clase en la que cada variable es utilizada por cada método es máximamente cohesiva.

En general, no es aconsejable ni posible crear clases tan cohesivas al máximo; por otro lado, nos gustaría que la cohesión fuera alta. Cuando la cohesión es alta, significa que los métodos y variables de la clase son codependientes y se mantienen unidos como un todo lógico.

La noción de cohesión está fuertemente relacionada con la noción de acoplamiento; Además, existe un principio basado en la heurística de alta cohesión, denominado Principio de Responsabilidad Única (la S de SOLID).


1
Creo que su respuesta es más completa que la aceptada, porque describe tanto el SRP como la cohesión, por lo que ayuda a comprender las especificidades y las diferencias entre estos dos conceptos.
The Once-ler

18

La alta cohesión es un concepto de ingeniería de software. Básicamente, dice que una clase solo debe hacer lo que se supone que debe hacer y lo hace completamente. No lo sobrecargue con funciones que se supone que no debe hacer, y lo que esté directamente relacionado con él tampoco debería aparecer en el código de alguna otra clase.

El ejemplo es bastante subjetivo, ya que también tenemos que considerar la escala. Un programa simple no debe estar demasiado modularizado o estará fragmentado; mientras que un programa complejo puede necesitar más nivel de abstracciones para ocuparse de la complejidad.

por ejemplo, clase de correo electrónico. Debe contener miembros de datos a, desde, cc, bcc, asunto, cuerpo y puede contener estos métodos saveAsDraft (), send (), discardDraft (). Pero login () no debería estar aquí, ya que hay varios protocolos de correo electrónico y deberían implementarse por separado.


Es la definición de SRP: "una clase solo debe hacer lo que se supone que debe hacer, y lo hace completamente".
AliN11

11

La cohesión generalmente se mide utilizando una de las métricas LCOM (Falta de cohesión), la métrica LCOM original proviene de Chidamber y Kemerer. Ver por ejemplo: http://www.computing.dcu.ie/~renaat/ca421/LCOM.html

Un ejemplo más concreto: si una clase tiene, por ejemplo, un campo privado y tres métodos; cuando los tres métodos usan este campo para realizar una operación, la clase es muy cohesiva.

Pseudo código de una clase cohesiva:

class FooBar {
  private SomeObject _bla = new SomeObject();

  public void FirstMethod() {
    _bla.FirstCall();
  }

  public void SecondMethod() {
    _bla.SecondCall();
  }

  public void ThirdMethod() {
    _bla.ThirdCall();
  }
}

Si una clase tiene, por ejemplo, tres campos privados y tres métodos; cuando los tres métodos usan solo uno de los tres campos, entonces la clase es poco cohesiva.

Pseudocódigo de una clase poco cohesiva:

class FooBar {
  private SomeObject _bla = new SomeObject();
  private SomeObject _foo = new SomeObject();
  private SomeObject _bar = new SomeObject();

  public void FirstMethod() {
    _bla.Call();
  }

  public void SecondMethod() {
    _foo.Call();
  }

  public void ThirdMethod() {
    _bar.Call();
  }
}

El principio de la clase que hace una sola cosa es el Principio de Responsabilidad Única que proviene de Robert C. Martin y es uno de los principios SÓLIDOS . El principio prescribe que una clase debe tener una sola razón para cambiar.

Mantenerse cerca del principio de responsabilidad única podría resultar en un código más cohesivo, pero en mi opinión, estas son dos cosas diferentes.


4

Este es un ejemplo de baja cohesión:

class Calculator
{


     public static void main(String args[])
     {

          //calculating sum here
          result = a + b;
          //calculating difference here
          result = a - b;
          //same for multiplication and division
     }
}

Pero una alta cohesión implica que las funciones en las clases hacen lo que se supone que deben hacer (como se les llama). Y no una función que hace el trabajo de otra función. Entonces, lo siguiente puede ser un ejemplo de alta cohesión:

class Calculator
{


     public static void main(String args[])
     {

          Calculator myObj = new Calculator();
          System.out.println(myObj.SumOfTwoNumbers(5,7));
      }


     public int SumOfTwoNumbers(int a, int b)
     {

          return (a+b);
     }

     //similarly for other operations

}

3

Una forma general de pensar en el principio de cohesión es que debe ubicar un código junto con otro código que dependa de él o del que dependa. La cohesión puede y debe aplicarse a niveles de composición por encima del nivel de clase. Por ejemplo, un paquete o espacio de nombres idealmente debería contener clases que se relacionen con algún tema común y que sean más interdependientes que dependientes de otros paquetes / espacios de nombres. Es decir, mantenga las dependencias locales.


1

cohesión significa que una clase o un método hace un solo trabajo definido. el nombre del método o clase también debe ser autoexplicativo. por ejemplo, si escribe una calculadora, debe nombrar la clase "calculadora" y no "asdfghj". también debe considerar crear un método para cada tarea, por ejemplo, restar () agregar (), etc. El programador que podría usar su programa en el futuro sabe exactamente lo que están haciendo sus métodos. un buen nombre puede reducir los esfuerzos de comentarios

también un principio es SECO - no te repitas


1

El término cohesión se utilizó originalmente para describir módulos de código fuente como una medida cualitativa de qué tan bien se relacionaba el código fuente del módulo entre sí. La idea de cohesión se utiliza en una variedad de campos. Por ejemplo, un grupo de personas, como una unidad militar, puede ser cohesivo, lo que significa que las personas de la unidad trabajan juntas hacia un objetivo común.

La esencia de la cohesión del código fuente es que el código fuente de un módulo trabaje en conjunto hacia un objetivo común y bien definido. La cantidad mínima de código fuente necesaria para crear las salidas del módulo está en el módulo y no más. La interfaz está bien definida y las entradas fluyen a través de la interfaz y las salidas fluyen de regreso a través de la interfaz. No hay efectos secundarios y el énfasis está en el minimalismo.

Una ventaja de los módulos funcionalmente cohesivos es que desarrollar y automatizar pruebas unitarias es sencillo. De hecho, una buena medida de la cohesión de un módulo es lo fácil que es crear un conjunto completo de pruebas unitarias exhaustivas para el módulo.

Un módulo puede ser una clase en un lenguaje orientado a objetos o una función en un lenguaje funcional o un lenguaje no orientado a objetos como C. Gran parte del trabajo original en esta área de medición de la cohesión involucraba principalmente el trabajo con programas COBOL en IBM en el 1970, por lo que la cohesión definitivamente no es solo un concepto orientado a objetos.

La intención original de la investigación de la que surgió el concepto de cohesión y el concepto asociado de acoplamiento fue investigar cuáles eran las características de los programas que eran fáciles de entender, mantener y ampliar. El objetivo era poder aprender las mejores prácticas de programación, codificar esas mejores prácticas y luego enseñar las prácticas a otros programadores.

El objetivo de los buenos programadores es escribir código fuente cuya cohesión sea lo más alta posible dado el entorno y el problema que se está resolviendo. Esto implica que en una aplicación grande algunas partes del cuerpo del código fuente variarán de otras partes en cuanto al nivel de cohesión del código fuente en ese módulo o clase. Algunas veces, lo mejor que puede obtener es la cohesión temporal o secuencial debido al problema que está tratando de resolver.

El mejor nivel de cohesión es la cohesión funcional. Un módulo con cohesión funcional es similar a una función matemática en el sentido de que proporciona un conjunto de entradas y obtiene una salida específica. Un módulo verdaderamente funcional no tendrá efectos secundarios además de la salida ni mantendrá ningún tipo de estado. En cambio, tendrá una interfaz bien definida que encapsula la funcionalidad del módulo sin exponer ninguno de los componentes internos del módulo y la persona que usa el módulo proporcionará un conjunto particular de entradas y obtendrá una salida particular a cambio. Un módulo verdaderamente funcional también debería ser seguro para subprocesos.

Muchas bibliotecas de lenguajes de programación contienen varios ejemplos de módulos funcionales, ya sean clases, plantillas o funciones. Los ejemplos de cohesión más funcionales serían funciones matemáticas como pecado, coseno, raíz cuadrada, etc.

Otras funciones pueden tener efectos secundarios o mantener algún tipo de estado, lo que hace que el uso de esas funciones sea más complicado.

Por ejemplo, una función que lanza una excepción o establece una variable de error global ( errnoen C) o debe usarse en una secuencia (la strtok()función es un ejemplo de la biblioteca C estándar ya que mantiene un estado interno) o que proporciona un puntero que luego debe administrarse o enviar un registro a alguna utilidad de registro son todos ejemplos de una función que ya no es cohesión funcional.

He leído el libro original de Yourdon y Constantine, Structured Programming, donde me topé por primera vez con la idea de cohesión en la década de 1980 y el libro de Meilir Page-Jones Practical Guide to Structured Systems Design, y Page-Jones hizo un trabajo mucho mejor al describir tanto el acoplamiento como la cohesión. El libro de Yourdon y Constantine parece un poco más académico. El libro Code Complete de Steve McConnell es bastante bueno y práctico y la edición revisada tiene bastante que decir sobre las buenas prácticas de programación.


Dices que The minimum amount of source code needed to create the module outputs is in the module and no moreesto no está relacionado con la cohesión sino con DTSTTCPW
v.oddou

@ v.oddou, la cantidad mínima de código está realmente relacionada con la cohesión. Cuanto más código en un módulo que no está relacionado con las salidas del módulo, es más probable que el código tenga efectos secundarios y, por lo tanto, menor cohesión. Cada concepto tiene diferentes perspectivas, especialmente conceptos como Cohesión que son algo ambiguos. Las medidas de Cohesión son cualitativas y requieren una especie de lógica difusa para asignar un módulo en particular a una categoría u otra utilizando una rúbrica de algún tipo. Decir un código mínimo para las salidas no es una característica suficiente para una alta cohesión, solo una de varias.
Richard Chambers

1

La mayoría de las respuestas no explican qué es la cohesión, está bien definido en el código limpio del libro de tío bobs.

Las clases deben tener una pequeña cantidad de variables de instancia. Cada uno de los métodos de una clase debe manipular una o más de esas variables. En general, cuantas más variables manipula un método, más cohesivo es ese método con su clase. Una clase en la que cada variable es utilizada por cada método es máximamente cohesiva. En general, no es aconsejable ni posible crear clases tan cohesivas al máximo; por otro lado, nos gustaría que la cohesión fuera alta. Cuando la cohesión es alta, significa que los métodos y variables de la clase son codependientes y se mantienen unidos como un todo lógico.

Déjame explicarlo con una definición de clase.

class FooBar {
private _bla;
private _foo;
private _bar;

function doStuff()

   if(this._bla>10){
     this._foo = 10;
     this._bar = 20;
   }

}
function doOtherStuff(){

    if(this._foo==10){
       this._bar = 100;
       this._bla = 200;
    }
}

}

Si ve el ejemplo anterior, la clase es cohesiva, lo que significa que las variables se comparten entre la clase para trabajar juntas, se comparten más variables, lo que significa que la clase es altamente cohesiva y funciona como una sola unidad.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.