Cuando el acoplamiento eferente / aferente es bueno o malo

11

Tengo un examen de patrones de software esta semana y uno de los temas que debemos estudiar es el acoplamiento eferente y aferente.

Entiendo que un paquete tiene un alto Ce (acoplamiento eferente) si depende de varios otros tipos.

Por ejemplo:

class Car{
    Engine engine;
    Wheel wheel;
    Body body;
}

Esta clase tendría un acoplamiento eferente alto porque depende de los tipos de motor, rueda y cuerpo.

Mientras que el tipo "Rueda" tendría un alto Ca (acoplamiento aferente) si varios otros paquetes dependieran de él (automóvil, avión, bicicleta).

Una de las posibles preguntas en nuestro examen es, ¿cuándo es bueno o malo el acoplamiento eferente / aferente? Esto me parece extraño porque lógicamente un programa necesitaría paquetes / clases con un alto acoplamiento Efferente / Aferente.

¿Alguien tiene un ejemplo de cuándo / dónde un acoplamiento eferente o aferente alto es bueno / malo?

Gracias !

Tom Selleck
fuente
44
Si tan solo hubieran escogido términos más confusos que sonaran aún más parecidos ...
user949300

Respuestas:

11

El acoplamiento aferente puede evaluarse más fácilmente en términos de cuánto dolor causa / ahorra debido a la necesidad o probabilidad de cambio. Por ejemplo, tome su clase de rueda y digamos que muchos otros módulos la usan para construir varios tipos de vehículos. Si la clase de rueda es extremadamente estable, entonces este acoplamiento aferente es beneficioso ya que los vehículos necesitan ruedas y están usando una confiable. Si, por otro lado, la clase de la rueda es volátil en términos de mantenimiento, este acoplamiento aferente será un punto problemático a medida que introduzca cambios de última hora en muchos códigos.

El acoplamiento eferente es similar en concepto, pero se verá una propuesta de valor ligeramente diferente. Si tiene una clase de automóvil que depende directamente de muchas partes individuales (en lugar de decir "Motor" y "Chasis" solamente, y consisten en otras subpartes), la clase probablemente hace mucho y, por lo tanto, puede ser un mantenimiento de cuellos de botella. Es probable que los cambios en esa clase sean difíciles y riesgosos debido a su complejidad. Por otro lado, si el acoplamiento eferente es alto, pero en realidad es bastante coherente y claro, entonces no tiene una jerarquía de objetos y relaciones de las que preocuparse.

Cuando se trata de arquitectura / diseño, lo que realmente debe tener en cuenta son compensaciones prácticamente infinitas y estas métricas no son diferentes. Si desea descubrir un ejemplo de algo bueno o malo, juegue el juego "qué pasaría si". Imagine un ejemplo y diga "¿y si quisiera hacer X? ¿Cuánto apestaría eso?" Para X donde la respuesta es "mucho", tienes una desventaja y para X donde la respuesta es "eso sería realmente fácil" tienes una ventaja.

Erik Dietrich
fuente
5

Hablando en general, acoplamiento flojo:

positivo : protege una parte del sistema de los cambios en algo de lo que depende (acoplamiento aferente)

negativo : la relación puede ser más difícil de entender

Por ejemplo, si estuviera desarrollando un sistema que dependiera de HTTTP, decidiría si necesito acoplarme estrictamente o sin apretar a HTTP. Si pensara que es probable que el sistema cambie a un protocolo diferente, puedo elegir acoplarlo libremente, mientras que si acepto que HTTP es mi protocolo, podría acoplar firmemente ese protocolo para simplificar la comprensión.

Tenga en cuenta que algunas de las complejidades de WS * están en su desacoplamiento de HTTP como protocolo.

jayraynet
fuente
Respuesta inteligente, pero no veo cómo se relaciona con la pregunta, que se refería al acoplamiento eferente / aferente y no al acoplamiento apretado / suelto.
lbalazscs
Tienes razón, @lbalazscs. ¡No tengo idea de por qué respondí sin responder la pregunta!
jayraynet
1

Aferente

Si algo usa un montón de cosas diferentes (gran cantidad de acoplamientos aferentes), entonces podría ser propenso a romperse si alguna de esas cosas cambia.

Inestabilidad = 1

ingrese la descripción de la imagen aquí

Eferente

Si algo es usado por un montón de cosas diferentes (alto número de acoplamientos eferentes), entonces podría ser propenso a romper muchas cosas si cambia.

Inestabilidad = 0

ingrese la descripción de la imagen aquí

Estabilidad

La definición de Martin de "estabilidad" es una mezcla exótica entre "difícil de cambiar" y "tener pocas razones para cambiar". Sin embargo, su métrica de inestabilidad solo describe la "dificultad de cambio". Las "razones para cambiar" tendrán mucho más que ver con factores que no pueden calcularse fácilmente, como diseñar sus interfaces de manera adecuada, en un nivel apropiado de abstracción y comprender los requisitos del usuario final de manera más clara por adelantado.

Entonces, un acoplamiento eferente alto con un acoplamiento aferente bajo produce estabilidad (como en algo difícil de cambiar ya que romperá un montón de cosas), lo contrario produce inestabilidad (como en algo fácil de cambiar ya que no romperá un montón de cosas) .

Una gran cantidad de acoplamientos aferentes podría ser un indicador de que su diseño carece de enfoque: está utilizando un montón de cosas diferentes, por lo que tal vez carece de una responsabilidad clara y singular.

Inicialmente, una gran cantidad de acoplamientos eferentes podría interpretarse como algo realmente bueno, ya que indica que su diseño está siendo (re) utilizado ampliamente. Sin embargo, eso sería malo si se siente tentado a cambiar el diseño a menudo de manera que lo rompa todo. Entonces, con una gran cantidad de acoplamientos eferentes surge la necesidad de que dichos paquetes tengan "pocas o ninguna razón para cambiar". Los diseños deben ser estables en el sentido ideal de no tener razones para cambiar, ya que también serán muy difíciles de cambiar.

Principio de abstracciones estables

Conceptos como inversión de dependencia (que naturalmente requiere inyección de dependencia) y SAP (principio de abstracciones estables) sugieren que las dependencias fluyen hacia las abstracciones. Y hay una razón simple para considerar la "estabilidad" en el contexto de tener "pocas razones para cambiar". Una interfaz abstracta no menciona detalles concretos, solo se centra en "qué hacer" en lugar de "qué son las cosas" y, por lo tanto, tiene menos razones para cambiar. El puerto de gráficos acelerado en nuestras placas base (interfaz abstracta) tiene menos razones para sufrir un cambio de diseño que la GPU que se conecta (un detalle concreto).

Reusabilidad vs. Reutilización

Un tipo de métrica personal mía si puedo sugerir una que colisione un poco con la de Martin es esta noción que me gusta insistir en que las bibliotecas más reutilizables deberían tratar de reutilizar mínimamente otro código. Eso empuja la inestabilidad hacia un 0 difícil. Es por razones prácticas de tener razones mínimas para cambiar, pero también para promover la biblioteca más fácil de implementar. Una biblioteca de uso general y ampliamente utilizada que depende de una docena de bibliotecas diferentes tiene muchas razones para cambiar, así como una distribución incómoda que puede ser difícil de implementar. La diferencia aquí es que las "razones para cambiar" en mi caso se extienden incluso a la implementación, ya que proviene de una vista orientada a la biblioteca que busca lanzar versiones estables de la biblioteca. Martin podría descartar la implementación como una parte muy separada,

Desde el punto de vista de la distribución, la implementación y la interfaz se difuminan juntas para generar dependencias del usuario en una biblioteca estable o inestable. Desde el punto de vista de la interfaz, solo se utiliza la interfaz y los detalles de implementación asociados están completamente separados.

ChrisF
fuente