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


Estoy aprendiendo programación informática 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 tenerlo en el índice, ¿podría indicarme algunos enlaces sobre este tema? No encontré la página de Wikipedia sobre cohesión de ciencias de la computación informativa, ya que solo dice que es un medida cualitativa y no da ejemplos reales de código.

 66
Author: Martijn Pieters, 2012-05-31

9 answers

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

Tomemos este ejemplo:

Tiene una clase que agrega dos números, pero la misma clase crea una ventana que muestra el resultado. Esta es una clase de baja cohesión 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 adición es la lógica detrás se.

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

 200
Author: Andrei M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-31 08:47:48

Una explicación de lo que es del Código Completo de Steve McConnell :

La cohesión se refiere a qué tan cerca están todas las rutinas en una clase o el código en una rutina soporta un propósito central. Clases que contienen funcionalidad fuertemente relacionada se describen como cohesión, y el objetivo heurístico es hacer la cohesión tan fuerte como posible. La cohesión es una herramienta útil para gestionar la complejidad porque cuanto más código soporta una clase un propósito central, cuanto más fácilmente tu 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 un pequeño número de variables de instancia. Cada uno de los los métodos de una clase deben manipular una o más de esas variables. En general cuantas más variables manipula un método más cohesivo ese método es a su clase. Una clase en la que cada variable es usada por cada método es lo más cohesivo posible.

En general no es aconsejable tampoco es posible crear tales clases de máxima cohesión; por otra parte mano, nos gustaría que la cohesión sea alta. Cuando la cohesión es alta, significa que los métodos y variables de la clase son co-dependientes y aguanten juntos como un todo lógico.

La noción de cohesión está fuertemente relacionada con la noción de acoplamiento; también, hay un principio basado en la heurística de alta cohesión, llamado Principio de Responsabilidad Única (la S del SÓLIDO).

 33
Author: m3th0dman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-31 09:11:03

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 no se supone que haga, 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 ser demasiado modularizado o se fragmentará; mientras que un programa complejo puede necesitar más nivel de abstracciones para cuidar la complejidad.

Por ejemplo, clase de correo electrónico. Debe contener miembros de datos a, from, cc, bcc, subject, body, y puede contener estos métodos saveAsDraft(), send (), discardDraft (). Pero login () no debe estar aquí, ya que hay un número de protocolo de correo electrónico, y debe implementarse por separado.

 16
Author: nhahtdh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-31 08:52:32

La cohesión se mide generalmente usando una de las métricas LCOM (Falta de cohesión), la métrica LCOM original vino 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 utilizan este campo para realizar una operación, entonces 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 para 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.

Pseudo có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 hacer una cosa de clase es el Principio de Responsabilidad Única que viene 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.

Permanecer cerca de la Única El principio de responsabilidad podría resultar en un código más cohesivo, pero en mi opinión son dos cosas diferentes.

 7
Author: RBaarda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-01 08:26:08

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 la alta cohesión implica que las funciones en las clases hacen lo que se supone que deben hacer(como si fueran nombradas). Y no una función haciendo el trabajo de otra función. Por lo tanto, 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
Author: Kazekage Gaara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-31 08:47:35

Cohesión significa que una clase o un método hace solo un trabajo definido. el nombre del método o clase también debe explicarse por sí mismo. por ejemplo, si escribe una calculadora, debe nombrar a 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
Author: tagtraeumer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-31 08:46:00

Una forma general de pensar en el principio de cohesión es que debe localizar un código junto con otro código que dependa de él, o del que depende. La cohesión puede y debe aplicarse a los 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, mantener las dependencias locales.

 1
Author: Chris Chedgey - Structure101,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-01 09:43:24

El artículo de MSDN es probablemente más informativo que Wikipedia en este caso.

 0
Author: Jeff Watkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-31 08:46:00

El término cohesión se usó originalmente para describir módulos de código fuente como una medida cualitativa de cuán bien el código fuente del módulo estaba relacionado 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 en 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 en un módulo trabaja en conjunto hacia un común, bien definido objetivo. 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 vuelta a través de la interfaz. No hay efectos secundarios, y el énfasis está en el minimalismo.

Un beneficio 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 lenguaje no orientado a objetos como C. Gran parte del trabajo original en esta área de medición de la cohesión involucró principalmente el trabajo con programas COBOL en IBM en la década de 1970, por lo que la cohesión definitivamente no es solo un concepto orientado a objetos.

La intención original de la investigación a partir de la cual el concepto de cohesión y el concepto asociado de acoplamiento vino de fue la investigación en lo que donde 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ñarlas 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 de la fuente el cuerpo del código variará 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 puedes conseguir es cohesión temporal o secuencial debido al problema que estás 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 la que proporciona un conjunto de entradas y obtiene una salida específica. Un módulo verdaderamente funcional no tendrá efectos secundarios además del salida ni mantendrá ningún tipo de estado. En su lugar, 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 debe ser seguro para hilos.

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

Otras funciones pueden tener efectos secundarios o mantener el estado de algún tipo que resulta en hacer el uso de esas funciones más complicado.

Por ejemplo, una función que lanza una excepción o establece una variable de error global (errno en C) o debe usarse en una secuencia (strtok() la función es un ejemplo de la biblioteca estándar de C, ya que mantiene un estado interno) o que proporciona un puntero que luego debe ser administrado o emite 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 encontré 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 Constantino 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.

 0
Author: Richard Chambers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-28 20:48:56