Parece que no puedo entender el concepto de "acoplamiento flojo". Supongo que no ayuda que la palabra "flojo" generalmente tenga una connotación negativa, así que siempre olvido que el acoplamiento flojo es algo bueno .
¿Alguien mostrará algún código de "antes" y "después" (o pseudocódigo) que ilustre este concepto?
oop
language-agnostic
loose-coupling
trebormf
fuente
fuente
Respuestas:
Considere una aplicación simple de carrito de compras que utiliza una clase CartContents para realizar un seguimiento de los artículos en el carrito de compras y una clase Order para procesar una compra. El pedido debe determinar el valor total de los contenidos en el carrito, podría hacerlo así:
Ejemplo estrechamente acoplado:
Observe cómo el método OrderTotal (y, por lo tanto, la clase Order) depende de los detalles de implementación de las clases CartContents y CartEntry. Si intentáramos cambiar esta lógica para permitir descuentos, probablemente tendríamos que cambiar las 3 clases. Además, si cambiamos a usar una colección de Lista para realizar un seguimiento de los artículos, también tendríamos que cambiar la clase de Pedido.
Ahora, aquí hay una forma ligeramente mejor de hacer lo mismo:
Ejemplo menos acoplado:
La lógica que es específica para la implementación de la línea de pedido del carrito o la colección del carrito o el pedido está restringida solo a esa clase. Por lo tanto, podríamos cambiar la implementación de cualquiera de estas clases sin tener que cambiar las otras clases. Podríamos llevar este desacoplamiento aún más lejos mejorando el diseño, introduciendo interfaces, etc., pero creo que entiendes el punto.
fuente
Order
tener conocimiento de aCart
. Las compras en vivo y la facturación son dos contextos diferentes. Cuando el cliente está listo para pagar, puede tener un proceso responsable de traducir las Entradas de carrito en algo significativo para elOrder
. De esta manera, laOrder
clase también se instanciaría y se usaría sin aCart
.CartEntry
yCartContents
. Dado que estos tienen un significado perfectamente claro, deberían modelarse simplemente como datos muertos. en términos de base de datos, todo lo que se necesita aquí es una tablaCREATE TABLE entry (price INTEGER, quantity INTEGER)
Muchos productos integrados (especialmente de Apple) como iPods , iPads son un buen ejemplo de acoplamiento apretado: una vez que la batería se agota, también podría comprar un nuevo dispositivo porque la batería está soldada y no se soltará, lo que hace que reemplazarla sea muy difícil. costoso. Un jugador débilmente acoplado permitiría cambiar sin esfuerzo la batería.
Lo mismo ocurre con el desarrollo de software: generalmente es (mucho) mejor tener un código débilmente acoplado para facilitar la extensión y el reemplazo (y hacer que las partes individuales sean más fáciles de entender). Pero, muy raramente, en circunstancias especiales, el acoplamiento estrecho puede ser ventajoso porque la estrecha integración de varios módulos permite una mejor optimización.
fuente
Usaré Java como ejemplo. Digamos que tenemos una clase que se ve así:
Cuando llame a la clase, tendré que hacer algo como esto:
Hasta aquí todo bien. Ahora digamos que tengo otra clase que se ve así:
Se ve exactamente igual que ABC, pero digamos que funciona a través de la red en lugar de en el disco. Así que ahora escribamos un programa como este:
Eso funciona, pero es un poco difícil de manejar. Podría simplificar esto con una interfaz como esta:
Ahora mi código puede verse así:
¿Ves cuánto más limpio y fácil de entender es eso? Acabamos de entender el primer principio básico del acoplamiento flexible: la abstracción. La clave desde aquí es asegurar que ABC y XYZ no dependan de ningún método o variable de las clases que los llaman. Eso permite que ABC y XYZ sean API completamente independientes. O, en otras palabras, están "desacoplados" o "poco acoplados" de las clases principales.
Pero, ¿y si necesitamos comunicación entre los dos? Bueno, entonces podemos usar más abstracciones como un modelo de evento para asegurarnos de que el código principal nunca necesite combinarse con las API que ha creado.
fuente
DiskAccessor
yNetworkAccessor
? No sé java ...Lo sentimos, pero el "acoplamiento flojo" no es un problema de codificación, es un problema de diseño. El término "acoplamiento flojo" está íntimamente relacionado con el estado deseable de "alta cohesión", siendo opuesto pero complementario.
El acoplamiento flojo simplemente significa que los elementos de diseño individuales deben construirse de manera que se reduzca la cantidad de información innecesaria que necesitan saber sobre otros elementos de diseño.
La alta cohesión es algo así como un "acoplamiento estrecho", pero la alta cohesión es un estado en el que los elementos de diseño que realmente necesitan conocerse entre sí están diseñados para que trabajen juntos de manera limpia y elegante.
El punto es que algunos elementos de diseño deben conocer detalles sobre otros elementos de diseño, por lo que deben diseñarse de esa manera y no accidentalmente. Otros elementos de diseño no deben conocer detalles sobre otros elementos de diseño, por lo que deben diseñarse de esa manera, a propósito, en lugar de al azar.
Implementar esto se deja como un ejercicio para el lector :).
fuente
El código estrechamente acoplado se basa en una implementación concreta. Si necesito una lista de cadenas en mi código y lo declaro así (en Java)
entonces soy dependiente de la implementación de ArrayList.
Si quiero cambiar eso a código débilmente acoplado, hago de mi referencia un tipo de interfaz (u otro resumen).
Esto me impide llamar a cualquier método
myList
específico para la implementación de ArrayList. Estoy limitado solo a los métodos definidos en la interfaz de Lista. Si luego decido que realmente necesito una LinkedList, solo necesito cambiar mi código en un lugar, donde creé la nueva Lista, y no en 100 lugares donde hice llamadas a los métodos ArrayList.Por supuesto, puede crear una instancia de ArrayList usando la primera declaración y no usar ningún método que no sea parte de la interfaz de la Lista, pero usar la segunda declaración hace que el compilador lo mantenga honesto.
fuente
El grado de diferencia entre las respuestas aquí muestra por qué sería un concepto difícil de entender, pero en términos tan simples como puedo describirlo:
Para que sepa que si te tiro una pelota, entonces puedes atraparla, realmente no necesito saber cuántos años tienes. No necesito saber qué comiste en el desayuno, y realmente no me importa quién fue tu primer enamoramiento. Todo lo que necesito saber es que puedes atrapar. Si sé esto, entonces no me importa si eres tú, te estoy lanzando una pelota a ti o a tu hermano.
Con lenguajes no dinámicos como c # o Java, etc., lo logramos mediante interfaces. Digamos que tenemos la siguiente interfaz:
Y ahora digamos que tenemos las siguientes clases:
Ahora, tanto CatcherA como CatcherB implementan el método Catch, por lo que el servicio que requiere un Catcher puede usar cualquiera de estos y realmente no importa cuál sea. Por lo tanto, un servicio estrechamente acoplado podría instanciar directamente
Por lo tanto, CatchService puede hacer exactamente lo que se propuso, pero utiliza CatcherA y siempre usará CatcherA. Está codificado, por lo que se queda allí hasta que alguien venga y lo refactorice.
Ahora tomemos otra opción, llamada inyección de dependencia:
Entonces el calss que instans CatchService puede hacer lo siguiente:
o
Esto significa que el servicio Catch no está estrechamente acoplado a CatcherA ni a CatcherB.
Hay varias otras estrategias para acoplar servicios como este, como el uso de un marco IoC, etc.
fuente
Puede pensar que el acoplamiento (apretado o suelto) es literalmente la cantidad de esfuerzo que le tomaría separar una clase en particular de su dependencia de otra clase. Por ejemplo, si cada método en su clase tenía un pequeño bloque finalmente en la parte inferior donde realizó una llamada a Log4Net para registrar algo, entonces diría que su clase estaba estrechamente unida a Log4Net. Si su clase contenía un método privado llamado LogSomething, que era el único lugar que llamaba al componente Log4Net (y los otros métodos a todos se llamaban LogSomething en su lugar), entonces diría que su clase estaba ligeramente acoplada a Log4Net (porque no tomaría mucho esfuerzo para extraer Log4Net y reemplazarlo con otra cosa).
fuente
64BitBob
más la respuesta, yo mismo.Definición
Esencialmente, el acoplamiento es cuánto depende un objeto o conjunto de objetos dado de otro objeto u otro conjunto de objetos para realizar su tarea.
Acoplamiento alto
Piensa en un auto. Para que el motor arranque, debe insertarse una llave en el encendido, girarse, la gasolina debe estar presente, debe producirse una chispa, los pistones deben disparar y el motor debe estar vivo. Se podría decir que el motor de un automóvil está altamente acoplado a varios otros objetos. Este es un acoplamiento elevado, pero en realidad no es algo malo.
Bajo acoplamiento
Piense en un control de usuario para una página web que sea responsable de permitir a los usuarios publicar, editar y ver algún tipo de información. El control único podría usarse para permitir que un usuario publique una nueva información o edite una nueva información. El control debe poder compartirse entre dos rutas diferentes: nueva y editar. Si el control está escrito de tal manera que necesita algún tipo de datos de las páginas que lo contendrán, entonces podría decir que está demasiado acoplado. El control no debería necesitar nada de su página de contenedor.
fuente
Es un concepto bastante general, por lo que los ejemplos de código no darán la imagen completa.
Un tipo aquí en el trabajo me dijo: "los patrones son como fractales, puedes verlos cuando te acercas muy cerca y cuando te alejas al nivel de la arquitectura".
Leer la breve página de Wikipedia puede darte una idea de esta generalidad:
http://en.wikipedia.org/wiki/Loose_coupling
En cuanto a un ejemplo de código específico ...
Aquí hay un acoplamiento suelto con el que he trabajado recientemente, de Microsoft.Practices.CompositeUI.
Este código declara que esta clase tiene una dependencia en un CustomizableGridService. En lugar de hacer referencia directa a la implementación exacta del servicio, simplemente establece que requiere ALGUNA implementación de ese servicio. Luego, en tiempo de ejecución, el sistema resuelve esa dependencia.
Si eso no está claro, puede leer una explicación más detallada aquí:
http://en.wikipedia.org/wiki/Dependency_injection
Imagine que ABCCustomizableGridService es la implementación que pretendo conectar aquí.
Si lo elijo, puedo sacarlo y reemplazarlo con XYZCustomizableGridService o StubCustomizableGridService sin ningún cambio en la clase con esta dependencia.
Si hubiera hecho referencia directa a ABCCustomizableGridService, entonces tendría que hacer cambios a esa / esas referencias / s para intercambiar otra implementación de servicio.
fuente
El acoplamiento tiene que ver con dependencias entre sistemas, que podrían ser módulos de código (funciones, archivos o clases), herramientas en una tubería, procesos servidor-cliente, etc. Cuanto menos generales son las dependencias, más "estrechamente acopladas" se vuelven, ya que cambiar un sistema requería cambiar los otros sistemas que dependen de él. La situación ideal es el "acoplamiento flojo", donde se puede cambiar un sistema y los sistemas que dependen de él continuarán funcionando sin modificaciones.
La forma general de lograr un acoplamiento flexible es a través de interfaces bien definidas. Si la interacción entre dos sistemas está bien definida y respetada en ambos lados, entonces será más fácil modificar un sistema y garantizar que las convenciones no se rompan. Comúnmente ocurre en la práctica que no se establece una interfaz bien definida, lo que resulta en un diseño descuidado y un acoplamiento estrecho.
Algunos ejemplos:
La aplicación depende de una biblioteca. Bajo un acoplamiento estrecho, la aplicación se rompe en las versiones más nuevas de la lib. Google para "DLL Hell".
La aplicación cliente lee datos de un servidor. Bajo un acoplamiento estrecho, los cambios en el servidor requieren correcciones en el lado del cliente.
Dos clases interactúan en una jerarquía orientada a objetos. Bajo un acoplamiento estrecho, los cambios en una clase requieren que la otra clase se actualice para que coincida.
Múltiples herramientas de línea de comandos se comunican en una tubería. Si están estrechamente acoplados, los cambios en la versión de una herramienta de línea de comandos provocarán errores en las herramientas que leen su salida.
fuente
El acoplamiento se refiere a cuán estrechamente diferentes clases están conectadas entre sí. Las clases estrechamente acopladas contienen una gran cantidad de interacciones y dependencias.
Las clases poco acopladas son lo opuesto en que sus dependencias entre sí se mantienen al mínimo y, en cambio, dependen de las interfaces públicas bien definidas entre sí.
Legos, los juguetes que SNAP juntos se considerarían sueltos porque puedes unir las piezas y construir el sistema que quieras. Sin embargo, un rompecabezas tiene piezas que están estrechamente acopladas. No puede tomar una pieza de un rompecabezas (sistema) y encajarla en un rompecabezas diferente, porque el sistema (rompecabezas) depende mucho de las piezas muy específicas que se construyeron específicamente para ese "diseño" en particular. Los legos están construidos de una manera más genérica para que puedan usarse en su Lego House o en mi Lego Alien Man.
Referencia: https://megocode3.wordpress.com/2008/02/14/coupling-and-cohesion/
fuente
Dos componentes están altamente acoplados cuando dependen de una implementación concreta el uno del otro.
Supongamos que tengo este código en algún lugar de un método en mi clase:
Ahora mi clase depende de SomeObject, y están muy acoplados. Por otro lado, digamos que tengo un método InjectSomeObject:
Entonces, el primer ejemplo puede usar SomeObject inyectado. Esto es útil durante las pruebas. Con la operación normal, puede usar clases pesadas que usan bases de datos, redes, etc., mientras que para las pruebas que pasan una implementación ligera y simulada. Con un código estrechamente acoplado no puedes hacer eso.
Puede facilitar algunas partes de este trabajo utilizando contenedores de inyección de dependencia. Puede leer más sobre DI en Wikipedia: http://en.wikipedia.org/wiki/Dependency_injection .
A veces es fácil llevar esto demasiado lejos. En algún momento tienes que hacer las cosas concretas, o tu programa será menos legible y comprensible. Por lo tanto, use estas técnicas principalmente en el límite de componentes y sepa lo que está haciendo. Asegúrese de aprovechar el acoplamiento suelto. Si no, probablemente no lo necesites en ese lugar. DI puede hacer que su programa sea más complejo. Asegúrate de hacer una buena compensación. En otras palabras, mantenga un buen equilibrio. Como siempre al diseñar sistemas. ¡Buena suerte!
fuente
Considere una aplicación de Windows con FormA y FormB. FormA es el formulario principal y muestra FormB. Imagine que FormB necesita pasar datos a su padre.
Si hiciste esto:
FormB está estrechamente acoplado a FormA. FormB no puede tener otro padre que el de tipo FormA.
Si, por otro lado, hizo que FormB publicara un evento y que FormA se suscribiera a ese evento, entonces FormB podría enviar los datos a través de ese evento a cualquier suscriptor que tenga ese evento. En este caso, entonces, FormB ni siquiera sabe si está respondiendo a su padre; A través del acoplamiento flexible, el evento proporciona que simplemente está hablando con los suscriptores. Cualquier tipo ahora puede ser padre de FormA.
rp
fuente
En informática hay otro significado para "acoplamiento flojo" que nadie más ha publicado aquí, así que ... Aquí va, ¡espero que me den algunos votos para que esto no se pierda en el fondo del montón! CIERTAMENTE el tema de mi respuesta pertenece a cualquier respuesta integral a la pregunta ... A saber:
El término "acoplamiento flojo" entró por primera vez en computación como un término usado como adjetivo con respecto a la arquitectura de la CPU en una configuración de múltiples CPU. Su término de contraparte es "acoplamiento apretado". El acoplamiento flojo es cuando las CPU no comparten muchos recursos en común y el acoplamiento apretado es cuando lo hacen.
El término "sistema" puede ser confuso aquí, así que por favor analice la situación con cuidado.
Por lo general, pero no siempre, múltiples CPU en una configuración de hardware en la que existen dentro de un sistema (como en cajas individuales de "PC") estarían estrechamente acopladas. Con la excepción de algunos sistemas de súper alto rendimiento que tienen subsistemas que realmente comparten memoria principal a través de "sistemas", todos los sistemas divisibles están débilmente acoplados.
Los términos Tightly Coupled y Loosely Coupled se introdujeron antes de que se inventaran las CPU multiproceso y multinúcleo, por lo que estos términos pueden necesitar algunos compañeros para articular completamente la situación actual. Y, de hecho, hoy en día es muy posible que tenga un sistema que abarque ambos tipos en un sistema general. Con respecto a los sistemas de software actuales, hay dos arquitecturas comunes, una de cada variedad, que son lo suficientemente comunes como para que sean conocidas.
Primero, dado que se trataba de la pregunta, algunos ejemplos de sistemas de acoplamiento flexible:
En contraste, algunos ejemplos estrechamente acoplados:
En la informática actual, los ejemplos de ambos que operan en un solo sistema general no son infrecuentes. Por ejemplo, tome las modernas CPU Pentium de doble o cuádruple núcleo que ejecutan Fedora 9: estos son sistemas informáticos estrechamente acoplados. Luego, combine varios de ellos en un clúster de Linux débilmente acoplado y ahora tendrá una computación flexible y estrechamente acoplada. ¡Oh, no es maravilloso el hardware moderno!
fuente
En lenguaje simple, acoplado libremente significa que no depende de otro evento para ocurrir. Se ejecuta de forma independiente.
fuente
Algunas respuestas largas aquí. Sin embargo, el principio es muy simple. Presento la declaración de apertura de wikipedia :
"El acoplamiento flexible describe una relación resistente entre dos o más sistemas u organizaciones con algún tipo de relación de intercambio.
Cada extremo de la transacción hace explícitos sus requisitos y hace pocas suposiciones sobre el otro extremo ".
fuente
Propongo una prueba muy simple de acoplamiento de código :
La pieza A de código está estrechamente acoplada a la pieza B de código si existe alguna modificación posible a la pieza B que forzaría cambios en la pieza A para mantener la corrección.
La pieza A de código no está estrechamente acoplada a la pieza B de código si no hay una posible modificación a la pieza B que haga necesario un cambio a la pieza A.
Esto lo ayudará a verificar cuánto acoplamiento hay entre las partes de su código. para razonar sobre eso, vea esta publicación de blog: http://marekdec.wordpress.com/2012/11/14/loose-coupling-tight-coupling-decoupling-what-is-that-all-about/
fuente
Cuando crea un objeto de una clase usando una
new
palabra clave en otra clase, en realidad está haciendo un acoplamiento estrecho (mala práctica) en su lugar, debe usar un acoplamiento suelto, que es una buena práctica--- A.java ---
--- B.java ---
--- InterfaceClass ---
---Clase principal---
Explicación:
En el ejemplo anterior, tenemos dos clases A y B
La clase B implementa Interface, es decir, InterfaceClass.
InterfaceClass define un contrato para la clase B ya que InterfaceClass tiene métodos abstractos de clase B a los que puede acceder cualquier otra clase, por ejemplo A.
En la Clase A tenemos un método de visualización que puede excepto el objeto de la clase que implementa InterfaceClass (en nuestro caso es la clase B). Y en ese objeto, el método de clase A está llamando a display () y getVar () de clase B
En MainClass hemos creado objetos de clase A y B. Y llamando al método de visualización de A pasando un objeto de clase B, es decir, objb. Se llamará al método de visualización de A con el objeto de la clase B.
Ahora hablando de acoplamiento flojo. Supongamos que en el futuro tiene que cambiar el nombre de la Clase B a ABC y luego no tiene que cambiar su nombre en el método de visualización de la clase B, simplemente haga el objeto de nuevo (clase ABC) y páselo al método de visualización en MailClass. No tiene que cambiar nada en la Clase A
ref: http://p3lang.com/2013/06/loose-coupling-example-using-interface/
fuente
Puede leer más sobre el concepto genérico de "acoplamiento flojo" .
En resumen, es una descripción de una relación entre dos clases, donde cada clase sabe muy poco sobre la otra y cada clase podría continuar funcionando bien, independientemente de si la otra está presente o no y sin dependencia de la implementación particular de la otra. clase.
fuente
El acoplamiento flojo, en general, es de 2 actores que trabajan independientemente uno del otro en la misma carga de trabajo. Entonces, si tuviera 2 servidores web que usaran la misma base de datos de back-end, entonces diría que esos servidores web están débilmente acoplados. El acoplamiento estricto se ejemplificaría con 2 procesadores en un servidor web ... esos procesadores están estrechamente acoplados.
Espero que sea de alguna ayuda.
fuente