Soy un estudiante que recientemente se unió a una empresa de desarrollo de software como pasante. De vuelta en la universidad, uno de mis profesores solía decir que tenemos que esforzarnos por lograr «Bajo acoplamiento y alta cohesión».

Entiendo el significado de bajo acoplamiento. Significa mantener el código de componentes separados por separado, de modo que un cambio en un lugar no rompa el código en otro.

Pero, ¿qué se entiende por alta cohesión? Si significa integrar bien las distintas piezas del mismo componente entre sí, no entiendo cómo se vuelve ventajoso.

¿Qué se entiende por alta cohesión? ¿Se puede explicar un ejemplo para comprender sus beneficios?

Comentarios

  • posible duplicado de ¿Hay ¿Métricas para la cohesión y el acoplamiento?
  • ¿El artículo de Wikipedia no responde suficientemente a su pregunta? en.wikipedia.org/wiki/Cohesion_(computer_science)
  • Hay un buen artículo sobre esto en: msdn.microsoft.com/en-us/magazine/cc947917.aspx
  • @EoinCarroll: Desafortunadamente, el artículo de wikipedia en este momento no da nada bueno ejemplos concretos con los que pueden trabajar los nuevos programadores. La teoría es buena y todo, pero no ' realmente se mantiene hasta que ' haya cometido los errores relacionados con la baja cohesión. La alta cohesión es uno de esos temas que me ha llevado varios años de programación para comprender completamente por qué es importante y cómo lograrlo.
  • Nunca entendí realmente la cohesión hasta que leí Código limpio. Usted también debería hacerlo.

Respuesta

Una forma de ver la cohesión en términos de OO es si los métodos en la clase está usando cualquiera de los atributos privados. Usando métricas como LCOM4 (Falta de métodos cohesivos), como lo señaló gnat en esta respuesta aquí , puede identificar clases que podrían refactorizarse. La razón por la que desea refactorizar métodos o clases para que sean más cohesivos es que simplifica el diseño del código para que otros lo usen . Créeme; a la mayoría de los líderes de tecnología y programadores de mantenimiento les encantará cuando solucione estos problemas.

Puede utilizar herramientas en su proceso de compilación, como Sonar para identificar baja cohesión en la base del código. Hay un par de casos muy comunes en los que puedo pensar donde los métodos son bajos en «cohesión» :

Caso 1: El método no está relacionado con la clase en absoluto

Considere el siguiente ejemplo:

 public class Food { private int _foodValue = 10; public void Eat() { _foodValue -= 1; } public void Replenish() { _foodValue += 1; } public void Discharge() { Console.WriteLine("Nnngghhh!"); } }  

Uno de los métodos , Discharge(), carece de cohesión porque no toca a ninguno de los miembros privados de la clase. En este caso, solo hay un miembro privado: _foodValue. Si no hace nada con los componentes internos de la clase, ¿realmente pertenece allí? El método podría moverse a otra clase que podría llamarse, por ejemplo, FoodDischarger.

 // Non-cohesive function extracted to another class, which can // be potentially reused in other contexts public FoodDischarger { public void Discharge() { Console.WriteLine("Nnngghhh!"); } }  

Si lo haces en Javascript, dado que las funciones son objetos de primera clase, la descarga puede ser una función gratuita:

 function Food() { this._foodValue = 10; } Food.prototype.eat = function() { this._foodValue -= 1; }; Food.prototype.replenish = function() { this._foodValue += 1; }; // This Food.prototype.discharge = function() { console.log("Nnngghhh!"); }; // can easily be refactored to: var discharge = function() { console.log("Nnngghhh!"); }; // making it easily reusable without creating a class  

Caso 2: Clase de utilidad

Este es en realidad un caso común que rompe la cohesión. Todo el mundo ama las clases de utilidad, pero estas generalmente indican fallas de diseño y la mayoría de las veces hace que el código base sea más complicado de mantener (debido a la alta dependencia asociada con las clases de utilidad). Considere las siguientes clases:

 public class Food { public int FoodValue { get; set; } } public static class FoodHelper { public static void EatFood(Food food) { food.FoodValue -= 1; } public static void ReplenishFood(Food food) { food.FoodValue += 1; } }  

Aquí podemos ver que la clase de utilidad necesita para acceder a una propiedad en la clase Food. Los métodos en la clase de utilidad no tienen cohesión en absoluto en este caso porque necesita recursos externos para hacer su trabajo. En este caso, ¿no sería mejor tener los métodos en la clase con la que están trabajando? ( como en el primer caso)?

Caso 2b: Objetos ocultos en clases de utilidad

Hay otro caso de clases de utilidad donde hay objetos de dominio no realizados. La primera reacción instintiva un programador tiene cuando programar la manipulación de cadenas es escribir una clase de utilidad para ello.Como el de aquí que valida un par de representaciones de cadenas comunes:

 public static class StringUtils { public static bool ValidateZipCode(string zipcode) { // validation logic } public static bool ValidatePhoneNumber(string phoneNumber) { // validation logic } }  

¿Qué la mayoría no se da cuenta de que un código postal, un número de teléfono o cualquier otra repetición de cadena puede ser un objeto en sí mismo:

 public class ZipCode { private string _zipCode; public bool Validates() { // validation logic for _zipCode } } public class PhoneNumber { private string _phoneNumber; public bool Validates() { // validation logic for _phoneNumber } }  

La noción de que no debe» t «manejar cadenas» directamente se detalla en esta publicación de blog de @codemonkeyism , pero está estrechamente relacionado con la cohesión porque la forma en que los programadores usan cadenas al poner lógica en las clases de utilidad.

Comentarios

Respuesta

Alta cohesión significa mantener juntas cosas similares y relacionadas, unir o fusionar partes que comparten contenido, funcionalidad, motivo u objetivo . En otras palabras, una cohesión baja podría significar, por ejemplo, una función / clase / entidad de código que sirve para múltiples propósitos en lugar de ser « al grano «. Una de las ideas que se llevan a cabo es hacer una cosa y hacerlo bien . Otros podrían incluir el hecho obvio de que no se replica una funcionalidad similar en muchos lugares. Esto también mejora la localidad del código base, ciertos tipos de cosas se encuentran en un lugar determinado (archivo, clase, conjunto de funciones, …) en lugar de estar dispersas.

Como ejemplo, considere una clase que tiene dos o tres propósitos: Carga / almacena recursos (por ejemplo, un archivo) y luego analiza y muestra el Esta clase tiene una cohesión baja porque gestiona al menos dos tareas separadas que no están relacionadas en absoluto (E / S de archivos, análisis y visualización). Un diseño de alta cohesión podría usar clases distintas para cargar y almacenar el recurso, analizarlo y luego mostrarlo.

Por otro lado, el acoplamiento bajo tiene como objetivo mantener las cosas distintas separadas, para que interactúen entre sí. lo menos posible, lo que reduce la complejidad y simplifica el diseño.

Respuesta

Significa que las partes de un objeto están estrechamente relacionadas con la función del objeto. Esto significa que hay muy poco o ningún desperdicio dentro del objeto en términos de función o responsabilidad. Esto, a su vez, puede mejorar la comprensión de para qué se supone que se usa el objeto en cuestión.

Comentarios

  • doesn ' ¿No se aplica también a un nivel superior al de los objetos? por ejemplo, agrupar objetos / funciones relacionados con una tarea en espacios de nombres?

Deja una respuesta

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