poo ley demeter bajo alta acoplamiento oop refactoring coupling law-of-demeter cohesion

oop - bajo - Acoplamiento, Cohesión y la Ley de Demeter



bajo acoplamiento y alta cohesion (6)

La Ley de Demeter indica que solo debes hablar sobre objetos que conoces directamente. Es decir, no realice el método de encadenamiento para hablar con otros objetos. Cuando lo hace, está estableciendo vínculos inadecuados con los objetos intermedios, coupling su código de forma inapropiada a otro código.

Eso es malo.

La solución sería que la clase que conoces exponga esencialmente envoltorios simples que delegan la responsabilidad al objeto con el que tiene relación.

Eso es bueno.

Pero, eso parece dar como resultado que la clase tenga baja cohesion . Ya no es simplemente responsable de lo que hace exactamente, sino que también tiene delegados que, en cierto sentido, hacen que el código sea menos cohesivo al duplicar partes de la interfaz de su objeto relacionado.

Eso es malo.

¿De verdad resulta en la reducción de la cohesión? ¿Es el menor de dos males?

¿Es esta una de esas áreas grises del desarrollo, donde puedes debatir dónde está la línea, o hay formas sólidas y basadas en principios de tomar una decisión sobre dónde trazar la línea y qué criterios puedes usar para tomar esa decisión?


Creo que puedes haber entendido mal lo que significa cohesión. Una clase que se implementa en términos de varias otras clases no necesariamente tiene baja cohesión, siempre que represente un concepto claro y tenga un propósito claro. Por ejemplo, puede tener una class Person , que se implementa en términos de clases Date (para la fecha de nacimiento), Address y Education (una lista de las escuelas a las que asistió la persona). Puede proporcionar envoltorios en Person para obtener el año de nacimiento, la última escuela a la que asistió o el estado donde vive, para evitar exponer el hecho de que la Person se implementa en términos de esas otras clases. Esto reduciría el acoplamiento, pero haría a la Person no menos cohesiva.


En las situaciones en las que parece haber una compensación entre el acoplamiento y la cohesión, probablemente me preguntaría "si alguien más ya hubiera escrito esta lógica, y estuviese buscando un error en ella, ¿dónde miraría primero?", Y escribe el código de esa manera.


Es un área gris Estos principios están destinados a ayudarte en tu trabajo, si encuentras que estás trabajando para ellos (es decir, se interponen en tu camino y / o te resulta complicado complicar tu código) entonces te estás conformando demasiado duro y necesitas para retroceder

Haga que funcione para usted, no trabaje para eso.


Grady Booch en "Análisis y Diseño Orientado a Objetos":

"La idea de cohesión también proviene del diseño estructurado. En pocas palabras, la cohesión mide el grado de conectividad entre los elementos de un solo módulo (y para el diseño orientado a objetos, una sola clase u objeto). La forma menos deseable de cohesión es coincidencia cohesión, en la que se arrojan abstracciones totalmente no relacionadas en la misma clase o módulo. Por ejemplo, considere una clase que comprende las abstracciones de perros y naves espaciales, cuyos comportamientos no están relacionados. La forma más deseable de cohesión es la cohesión funcional, en la que los elementos de una clase o módulo todos trabajan juntos para proporcionar un comportamiento bien delimitado. Por lo tanto, la clase Dog es funcionalmente cohesiva si su semántica abarca el comportamiento de un perro, el perro entero y nada más que el perro ".

Perro sustituto con el cliente en el anterior y podría ser un poco más claro. Entonces, el objetivo es simplemente apuntar a la cohesión funcional y alejarse de la cohesión casual tanto como sea posible. Dependiendo de sus abstracciones, esto puede ser simple o podría requerir alguna refactorización.

Tenga en cuenta que la cohesión se aplica tanto a un "módulo" como a una sola clase, es decir, un grupo de clases que trabajan juntas. Entonces, en este caso, las clases de Cliente y Orden todavía tienen una cohesión decente porque tienen esta relación fuerte, los clientes crean pedidos y los pedidos pertenecen a los clientes.

Martin Fowler dice que se sentiría más cómodo llamándolo la "Sugerencia de Demeter" (ver el artículo Las burlas no son talones ):

"Los probadores de Mockist sí hablan más sobre evitar cadenas de trenes" - cadenas de métodos de estilo de getThis (). GetThat (). GetTheOther (). Evitar cadenas de métodos también se conoce como seguir la Ley de Demeter. Mientras que las cadenas de métodos son un olor, el problema opuesto de los objetos de los hombres del medio hinchados con métodos de reenvío también es un olor. (Siempre he sentido que estaría más cómodo con la Ley de Demeter si se llamara la Sugerencia de Demeter ).

Eso resume muy bien de dónde vengo: es perfectamente aceptable y a menudo necesario tener un nivel de cohesión más bajo del que podría exigir el estricto cumplimiento de la "ley". Evite la cohesión casual y apunte a la cohesión funcional, pero no se obsesione con los ajustes donde sea necesario para encajar de forma más natural con su abstracción de diseño.


No sé si esto realmente reduce la cohesión.

La agregación / composición se trata de una clase que utiliza otras clases para cumplir con el contrato que expone a través de sus métodos públicos. La clase no necesita duplicar la interfaz de sus objetos relacionados. De hecho, está ocultando cualquier conocimiento sobre estas clases agregadas del llamador del método.

Para obedecer la ley de Demeter en el caso de niveles múltiples de dependencia de clase, solo necesita aplicar agregación / composición y buena encapsulación en cada nivel.

En otras palabras, cada clase tiene una o más dependencias en otras clases, sin embargo, estas solo son dependencias de la clase referenciada y no de objetos devueltos por derechos / métodos.


Si está violando la Ley de Demeter al tener

int price = customer.getOrder().getPrice();

la solución no es crear un getOrderPrice () y transformar el código en

int price = customer.getOrderPrice();

pero en vez de notar que este es un olor a código y realizar los cambios relevantes que, ojalá, aumenten la cohesión y reduzcan el acoplamiento. Desafortunadamente no hay una refactorización simple aquí que siempre se aplique, pero probablemente deberías aplicar decir no preguntar