¿Qué es el "acoplamiento flojo"? Por favor proporcione ejemplos


172

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?


No estoy seguro de cómo esto puede separarse de un idioma en particular porque parte del concepto es cómo uno usa un lenguaje para evitar que las unidades de código se enreden demasiado entre sí. También noto que varias de las respuestas recurren al código para ilustrar el concepto.
Onorio Catenacci

11
No estoy completamente de acuerdo, los aspectos prácticos se pueden ilustrar de manera diferente en diferentes idiomas, y es especialmente evidente en los lenguajes dinámicos frente a los compilados. Pero el concepto es el mismo en ambos sentidos.
Owen

Loose vs Tight y Coupling vs desacoplamiento . Seguir adelante no siempre es algo bueno, a veces bueno / a veces no bueno ... Como deberíamos tener independencia propia, también lo hacen las clases.
bonCodigo

Respuestas:


180

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:

public class CartEntry
{
    public float Price;
    public int Quantity;
}

public class CartContents
{
    public CartEntry[] items;
}

public class Order
{
    private CartContents cart;
    private float salesTax;

    public Order(CartContents cart, float salesTax)
    {
        this.cart = cart;
        this.salesTax = salesTax;
    }

    public float OrderTotal()
    {
        float cartTotal = 0;
        for (int i = 0; i < cart.items.Length; i++)
        {
            cartTotal += cart.items[i].Price * cart.items[i].Quantity;
        }
        cartTotal += cartTotal*salesTax;
        return cartTotal;
    }
}

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:

public class CartEntry
{
    public float Price;
    public int Quantity;

    public float GetLineItemTotal()
    {
        return Price * Quantity;
    }
}

public class CartContents
{
    public CartEntry[] items;

    public float GetCartItemsTotal()
    {
        float cartTotal = 0;
        foreach (CartEntry item in items)
        {
            cartTotal += item.GetLineItemTotal();
        }
        return cartTotal;
    }
}

public class Order
{
    private CartContents cart;
    private float salesTax;

    public Order(CartContents cart, float salesTax)
    {
        this.cart = cart;
        this.salesTax = salesTax;
    }

    public float OrderTotal()
    {
        return cart.GetCartItemsTotal() * (1.0f + salesTax);
    }
}

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.


¿Podría ampliar la respuesta introduciendo un mayor desacoplamiento a través de la inyección de dependencia (aunque el constructor debería ser ideal)?
BAD_SEED

44
@Wedge, no veo ninguna razón para Ordertener conocimiento de a Cart. 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 el Order. De esta manera, la Orderclase también se instanciaría y se usaría sin a Cart.
plalx

@Wedge ¿Podría reaccionar a mi comentario por favor?
plalx

Bien y simplemente explicado. Empecé a ver la luz en ".. 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 .."
okey_on

Este ejemplo se presenta claramente. Sin embargo, en estos días, cada vez más arquitectos están de acuerdo en que este estilo demasiado orientado a objetos es una mala práctica. No tiene sentido ocultar los detalles de "implementación" de CartEntryy CartContents. 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)
Jo So

160

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.


¿Es bueno el acoplamiento flojo o apretado? ¿Cómo decidir implementar un acoplamiento suelto o un acoplamiento apretado?
Sreekanth Karumanaghat

2
gracias por este gran ejemplo. Pasé mucho tiempo en otras respuestas, pero no valía la pena
Alamin

1
Sreekanth Karumanaghat, ¿preferiría gastar menos dinero solo por una batería y tener un iPod funcionando nuevamente o preferiría gastar mucho dinero en un iPod completo?
Koshera

1
@SreekanthKarumanaghat Normalmente, el acoplamiento suelto es mejor porque promueve la modularidad y, por lo tanto, hace que el código sea más fácil de mantener. Si combina estrechamente sus clases / bibliotecas / código, cualquier pequeño cambio que realice en una clase deberá implementarse en todas las clases que lo utilizan.
Kenny Worden

56

Usaré Java como ejemplo. Digamos que tenemos una clase que se ve así:

public class ABC
{
   public void doDiskAccess() {...}
}

Cuando llame a la clase, tendré que hacer algo como esto:

ABC abc = new ABC();

abc. doDiskAccess();

Hasta aquí todo bien. Ahora digamos que tengo otra clase que se ve así:

public class XYZ
{
   public void doNetworkAccess() {...}
}

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:

if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();

Eso funciona, pero es un poco difícil de manejar. Podría simplificar esto con una interfaz como esta:

public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}

Ahora mi código puede verse así:

Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();

¿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.


2
Este ejemplo todavía tiene un nivel bastante alto de acoplamiento. Justo ahora, en lugar de estar acoplado a una sola clase, hay dos para elegir. Este ejemplo asume que solo habrá dos implementaciones "Runnable" disponibles. En cuyo caso ni siquiera se requiere una interfaz.
Owen

Estos métodos nombrados Run * y Do * son un gran olor a código para mí. También podría refactorizar esto para usar IHandleStuff o IFrobnicateThings. Runnable es un término muy, muy genérico en este caso.
Wedge

8
Owen, mi bebé da unos pasos. Si no entiende el acoplamiento, ¿cómo va a entender qué le compra un patrón de fábrica? Este ejemplo de código lo coloca en el camino correcto. La intención es que comprenda mejor el problema y se dé cuenta de cómo abstraer la creación de los objetos.
64BitBob

66
¿Sería esto más legible si ABC y XYZ fueran renombrados como DiskAccessory NetworkAccessor? No sé java ...
MusiGenesis

¿También utiliza el patrón de diseño de fábrica? Porque estamos creando nuevos objetos XYZ o ABC dependiendo de la necesidad.
munmunbb

37

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 :).


33

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)

ArrayList<String> myList = new ArrayList<String>();

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).

List<String> myList = new ArrayList<String>();

Esto me impide llamar a cualquier método myListespecí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.


Esto difícilmente se relaciona con lo que realmente es "acoplamiento" . Consulte stackoverflow.com/questions/39946/coupling-and-cohesion para obtener algunas buenas respuestas.
Rogério

@Rogerio: Creo que se relaciona. Tal vez te confunden otras definiciones de "acoplamiento", pero deberías leer Acoplamiento suelto . "El acoplamiento fuerte ocurre cuando una clase dependiente contiene un puntero directamente a una clase concreta que proporciona el comportamiento requerido ... El acoplamiento flojo ocurre cuando la clase dependiente contiene un puntero solo a una interfaz, que luego puede ser implementada por una o muchas clases concretas ". En mi ejemplo, mi código se acoplaría libremente a una ArrayList a través de la interfaz List.
Bill the Lizard el

@Bill: Gracias por el enlace, pero ese artículo me parece completamente falso. Parece "reinterpretar" ideas de otro dominio (comportamiento organizacional), dando una definición de "acoplamiento flojo" que contradice la definición específica de software original de Larry Constantine: en.wikipedia.org/wiki/Coupling_(computer_science) .
Rogério

@Rogerio: El artículo de Constantine fue escrito en 1974. Es probable que se haya reinterpretado en los últimos 36 años, pero no creo que el artículo de Wikipedia sea su fuente. Por ejemplo, patrones como la inyección de dependencia dependen de interfaces para aflojar el acoplamiento tal como lo describo en mi respuesta.
Bill the Lizard el

2
@Bill: Claro, el trabajo de Constantine en diseño estructurado es algo viejo, pero no veo ninguna razón para invalidarlo o reinterpretarlo radicalmente. Los conceptos originales de cohesión y acoplamiento están en el núcleo del diseño orientado a objetos, tanto como la herencia y el polimorfismo. DI (un mejor artículo es martinfowler.com/articles/injection.html ) es simplemente una técnica para la configuración externa de complementos (interfaces abstractas con implementaciones seleccionadas en tiempo de ejecución a través del código de configuración); Otra de estas técnicas es el patrón Localizador de servicios. DI y acoplamiento son conceptos independientes.
Rogério

26

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:

public ICatcher
{
   public void Catch();
}

Y ahora digamos que tenemos las siguientes clases:

public CatcherA : ICatcher
{
   public void Catch()
   {
      console.writeline("You Caught it");
   }

}
public CatcherB : ICatcher
{
   public void Catch()
   {
      console.writeline("Your brother Caught it");
   }

}

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

public CatchService
{
   private CatcherA catcher = new CatcherA();

   public void CatchService()
   {
      catcher.Catch();
   }

}

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:

public CatchService
{
   private ICatcher catcher;

   public void CatchService(ICatcher catcher)
   {
      this.catcher = catcher;
      catcher.Catch();
   }
}

Entonces el calss que instans CatchService puede hacer lo siguiente:

CatchService catchService = new CatchService(new CatcherA());

o

CatchService catchService = new CatchService(new CatcherB());

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.


1
Este ejemplo me gusta más que los otros, ya que este tipo de cosas suceden en el mundo de los negocios en el día a día. Si Class Person corre, Class Cat corre, Class Dog corre, etc. Sería un gran programa detallar todas esas clases que corre. Pero el uso de una interfaz llamada carreras, donde cada clase hace lo mismo, hace que su programa sea mucho más flexible y manejable. :)
sksallaj

¿Explicado realmente bien señor, solo para aclarar en el último ejemplo que lo hizo con inyección de dependencia, y el primer ejemplo también está vagamente acoplado?
Ali Sajid

Wow, la vieja respuesta comentó :). Entonces, la respuesta es no, el primer ejemplo tiene una fuerte dependencia de CatcherA, por lo que están fuertemente acoplados
Owen el

23

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).


1
Entonces, ¿"acoplado libremente" en realidad significa menos dependencias? ¿Estoy en lo correcto?
user314362

44
No está realmente relacionado con el número total de dependencias que tiene una clase en particular. El acoplamiento (apretado o suelto) es en realidad una propiedad de la relación entre dos clases. Por lo tanto, es posible que tenga una clase que esté débilmente acoplada a otras 100 clases, u otra clase que esté estrechamente asociada a solo otras 2 clases (por ejemplo).
MusiGenesis

2
Mal ejemplo, yo diría: lo que tienes es duplicación de código, no acoplamiento estrecho. Y con una buena herramienta de refactorización, dicha duplicación podría eliminarse en segundos.
Rogério

@Rogerio: probablemente no sea el mejor ejemplo. Me gusta 64BitBobmás la respuesta, yo mismo.
MusiGenesis

12

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.


7

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.

    [ServiceDependency]
    public ICustomizableGridService CustomizableGridService
    {
        protected get { return _customizableGridService; }
        set { _customizableGridService = value; }
    }

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.


6

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.


5

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/


4

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:

this.some_object = new SomeObject();

Ahora mi clase depende de SomeObject, y están muy acoplados. Por otro lado, digamos que tengo un método InjectSomeObject:

void InjectSomeObject(ISomeObject so) { // note we require an interface, not concrete implementation
  this.some_object = so;
}

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!


3

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:

class FormA 
{
    FormB fb = new FormB( this );

    ...
    fb.Show();
}

class FormB 
{
    FormA parent;

    public FormB( FormA parent )
    {
        this.parent = parent;
    }     
}

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


3

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:

  • VaxClusters
  • Clusters de Linux

En contraste, algunos ejemplos estrechamente acoplados:

  • Sistemas operativos semiprocesados ​​(SMP): por ejemplo, Fedora 9
  • CPU multiproceso
  • CPU multinúcleo

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!


3

En lenguaje simple, acoplado libremente significa que no depende de otro evento para ocurrir. Se ejecuta de forma independiente.


1
Eso no es realmente cierto, como se mencionó en otros ejemplos, no se trata tanto de si existe una relación entre entidades (módulos, clases), sino de si se pueden intercambiar fácilmente por otras clases que implementen la misma funcionalidad. Por ejemplo, un ViewModel podría funcionar con diferentes modelos, pero definitivamente no funcionará sin uno
Hayden Crocker

eh, no muy útil
brgs

2

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 ".


1
Si fuera tan simple, no tendríamos esta discusión.
brgs

2

Propongo una prueba muy simple de acoplamiento de código :

  1. 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.

  2. 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/


2

Cuando crea un objeto de una clase usando una newpalabra 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 ---

package interface_package.loose_coupling;

public class A {

void display(InterfaceClass obji)
{
    obji.display();
    System.out.println(obji.getVar());
}
}

--- B.java ---

package interface_package.loose_coupling;

public class B implements InterfaceClass{

private String var="variable Interface";

public String getVar() {
    return var;
}

public void setVar(String var) {
    this.var = var;
}

@Override
public void display() {
    // TODO Auto-generated method stub
    System.out.println("Display Method Called");
}
}

--- InterfaceClass ---

package interface_package.loose_coupling;

public interface InterfaceClass {

void display();
String getVar();
}

---Clase principal---

package interface_package.loose_coupling;

public class MainClass {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    A obja=new A();
    B objb=new B();
    obja.display(objb);     //Calling display of A class with object of B class 

}
}

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/


0

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.


-8

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.


1
Veo lo que está buscando, pero todavía no es una muy buena manera de explicar que estrechamente acoplado es cuando dos 'cosas' son interdependientes entre sí, en comparación con un acoplamiento débil cuando dos 'cosas' existen independientemente, donde una 'cosa' puede cambiarse sin cambios a la otra 'cosa' ...
Bryan Rehbein

Steve, tienes toda la razón: no merecías NINGUNO de los votos negativos. Es solo que su audiencia no estaba lista para su terminología y muchos en este sitio tienen la costumbre de votar lo que no entienden o lo que no les es familiar. -shrug-
Richard T

Creo que Steve perdió el punto. El acoplamiento flexible no siempre implica que 2 actores trabajen independientemente en la misma carga de trabajo.
Rob
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.