oop - poo - ¿Cuál es la diferencia entre acoplamiento suelto y acoplamiento apretado en el paradigma orientado a objetos?
programacion orientada a objetos ejemplos (15)
¿Programa sabio diferencia entre el acoplamiento apretado y el acoplamiento flojo?
Acoplamiento apretado entre objetos Java
class Traveler
{
Car c=new Car();
void startJourney()
{
c.move();
}
}
class Car
{
void move()
{
// logic...
}
}
Acoplamiento suelto entre objetos Java
class Traveler
{
Vehicle v;
public void setV(Vehicle v)
{
this.v = v;
}
void startJourney()
{
v.move();
}
}
// ========================= Interfaz ====================== ==============
Interface Vehicle
{
void move();
}
// ==================== Interfaz de vehículo de implemento de clase múltiple. Primera clase ====
class Car implements Vehicle
{
public void move()
{
// logic
}
}
// =================== Segunda clase ================
class Bike implements Vehicle
{
public void move()
{
// logic
}
}
¿Puede alguien describir la diferencia exacta entre el acoplamiento suelto y el acoplamiento apretado en el paradigma orientado a objetos?
Explicación del concepto sin código.
Ejemplo de resumen:
El sombrero está "acoplado libremente" al cuerpo. Esto significa que puede quitarse el sombrero fácilmente sin realizar ningún cambio en la persona / cuerpo. Cuando puedes hacer eso, entonces tienes "acoplamiento suelto". Ver más abajo para la elaboración.
Acoplamiento apretado (Ejemplo detallado)
Piensa en tu piel. Está pegado a tu cuerpo. Se ajusta como un guante. Pero, ¿y si quisiera cambiar el color de su piel de blanco a negro? ¿Te imaginas lo doloroso que sería pelar tu piel, teñirla y luego volver a pegarla, etc.? Cambiar tu piel es difícil porque está fuertemente acoplado a tu cuerpo. Simplemente no puedes hacer cambios fácilmente. Tendrías que rediseñar fundamentalmente a un ser humano para que esto sea posible.
- Punto clave n. ° 1 : en otras palabras, si desea cambiar la piel, también TENDRÁ QUE cambiar el diseño de su cuerpo , ya que los dos están unidos entre sí, están bien acoplados.
Dios no era un buen programador orientado a objetos.
Acoplamiento suelto (Ejemplo detallado)
Ahora piensa en vestirse por la mañana. ¿No te gusta el azul? No hay problemas: puedes ponerte una camisa roja. Puede hacerlo fácilmente y sin esfuerzo, ya que la camisa no está realmente conectada a su cuerpo de la misma manera que su piel. La camisa no sabe ni se preocupa por qué cuerpo está pasando . En otras palabras, puedes cambiarte de ropa sin cambiar realmente tu cuerpo.
- Ese es el punto clave # 2. Si te cambias la camisa, entonces no estás obligado a cambiar tu cuerpo ; cuando puedes hacerlo, entonces tienes un acoplamiento suelto. Cuando no puedes hacer eso, entonces tienes un acoplamiento apretado.
Ese es el concepto básico en pocas palabras.
¿Por qué es todo esto importante?
Es importante porque el software cambia todo el tiempo. En general, usted desea poder modificar fácilmente su código.
ejemplos prácticos
- Si alguien desea su salida en un archivo CSV en lugar de JSON, etc., o si desea cambiar de MySQL a PostGreSQL, debería poder realizar esos cambios de manera extremadamente fácil en su código, sin tener que volver a escribir toda la clase y pasar 10 horas. depuración En otras palabras, no desea unir estrechamente su aplicación con una implementación de base de datos específica (por ejemplo, Mysql) o con una salida particular (por ejemplo, archivos CSV). Porque, como es inevitable en el software, vendrán cambios. Cuando llegan, es mucho más fácil si sus partes de su código están acopladas libremente.
- Si alguien quiere que su auto sea black , no debería tener que rediseñar todo el auto para hacer eso. Un automóvil y sus piezas de repuesto serían un ejemplo perfecto de una arquitectura débilmente acoplada (según los comentarios de @ mnmopazem). Si desea reemplazar su motor por uno mejor, debería poder simplemente quitarlo sin demasiado esfuerzo e intercambiarlo por uno mejor. Si su automóvil solo funciona con los motores Rolls Royce ABC1234 y ningún otro motor, entonces su automóvil estará fuertemente acoplado a ese motor (Rolls Royce ABC1234). (Por cierto si esa es tu contraseña, entonces te avergüenzo). Sería mejor si cambiara el diseño de su automóvil para que funcione con cualquier motor, de modo que esté un poco más suelto con sus componentes. ¡Aún mejor sería si su automóvil pudiera funcionar sin necesidad de un motor! Se va a producir una cierta cantidad de acoplamiento, pero debes trabajar para minimizarlo tanto como puedas. ¿Por qué? Porque cuando los requisitos cambian, aún deberíamos poder entregar software de buena calidad, muy rápidamente y se nos ayuda a lograr ese objetivo mediante el acoplamiento suelto.
Resumen
En resumen, el acoplamiento suelto facilita el cambio de código. Las respuestas anteriores proporcionan algún código que vale la pena leer en este momento.
Acoplamiento flojo significa que el grado de dependencia entre dos componentes es muy bajo Ex.GSM SIM El acoplamiento apretado significa que el grado de dependencia entre dos componentes es muy alto. ex. CDMA Mobile
Cuando dos objetos están ligeramente acoplados, pueden interactuar pero tienen muy poco conocimiento entre sí.
Los diseños poco acoplados nos permiten construir sistemas OO flexibles que pueden manejar el cambio.
El patrón de diseño del observador es un buen ejemplo para hacer que las clases se emparejen libremente, puede verlo en en.wikipedia.org/wiki/Observer_pattern .
El acoplamiento apretado es cuando un grupo de clases es altamente dependiente unas de otras.
Este escenario surge cuando una clase asume demasiadas responsabilidades, o cuando una preocupación se extiende entre muchas clases en lugar de tener su propia clase.
El acoplamiento suelto se logra mediante un diseño que promueve la responsabilidad única y la separación de preocupaciones.
Una clase con acoplamiento flexible se puede consumir y probar independientemente de otras clases (concretas).
Las interfaces son una herramienta poderosa para usar para el desacoplamiento. Las clases pueden comunicarse a través de interfaces en lugar de otras clases concretas, y cualquier clase puede estar en el otro extremo de esa comunicación simplemente implementando la interfaz.
Ejemplo de acoplamiento apretado:
class CustomerRepository
{
private readonly Database database;
public CustomerRepository(Database database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
class Database
{
public void AddRow(string Table, string Value)
{
}
}
Ejemplo de acoplamiento suelto:
class CustomerRepository
{
private readonly IDatabase database;
public CustomerRepository(IDatabase database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
interface IDatabase
{
void AddRow(string Table, string Value);
}
class Database : IDatabase
{
public void AddRow(string Table, string Value)
{
}
}
Otro ejemplo here .
El acoplamiento apretado significa que una clase depende de otra clase. Acoplamiento flojo significa que una clase depende de la interfaz rathar que de la clase.
En el acoplamiento apretado, hay una dependencia codificada en los métodos declarada. En el acoplamiento suelto, debemos pasar la dependencia externamente en tiempo de ejecución en lugar de codificada (los sistemas de pareja suelta son una interfaz de uso para disminuir la dependencia con la clase)
Por ejemplo, tenemos un sistema que puede enviar salidas de dos o más formas como JSON-Output, CSV-Output, etc.
Apretado acoplado
public interface OutputGenerator {
public void generateOutput();
}
public class CSVOutputGenerator implements OutputGenerator {
public void generateOutput() {
System.out.println("CSV Output Generator");
}
}
public class JSONOutputGenerator implements OutputGenerator {
public void generateOutput() {
System.out.println("JSON Output Generator");
}
}
// In Other Code, we write Output Generator like...
public class Class1 {
public void generateOutput() {
// Here Output will be in CSV-Format, because of hard-coded code.
// This method tightly coupled with CSVOutputGenerator class, if we want another Output, we must change this method.
// Any method, that calls Class1''s generateOutput will return CSVOutput, because Class1 is tight couple with CSVOutputGenerator.
OutputGenerator outputGenerator = new CSVOutputGenerator();
output.generateOutput();
}
}
En el ejemplo anterior, si queremos cambiar la salida en JSON, necesitamos encontrar y cambiar todo el código, porque Class1 está estrechamente agrupada con la clase CSVOutputGenerator.
Suelto acoplado
public interface OutputGenerator {
public void generateOutput();
}
public class CSVOutputGenerator implements OutputGenerator {
public void generateOutput() {
System.out.println("CSV Output Generator");
}
}
public class JSONOutputGenerator implements OutputGenerator {
public void generateOutput() {
System.out.println("JSON Output Generator");
}
}
// In Other Code, we write Output Generator like...
public class Class1 {
public void generateOutput(OutputGenerator outputGenerator) {
// if you want to write JSON, pass object of JSONOutputGenerator (Dependency will be passed externally to this method)
// if you want to write CSV, pass object of CSVOutputGenerator (Dependency will be passed externally to this method)
// Due to loose couple with class, we don''t need to change code of Class1, because Class1 is loose coupled with CSVOutputGenerator or JSONOutputGenerator class
// Any method, that calls Class1''s generateOutput will desired output, because Class1 does not tight couple with CSVOutputGenerator or JSONOutputGenerator class
OutputGenerator outputGenerator = outputGenerator;
output.generateOutput();
}
}
El acoplamiento suelto es el proceso de dar la dependencia que su clase necesita indirectamente sin proporcionar toda la información de la dependencia (es decir, en la interfaz de usuario) en caso de que el acoplamiento estricto se dé directamente en la dependencia, lo que no es una buena forma de codificación.
El acoplamiento suelto es una respuesta a las dependencias codificadas al estilo antiguo y problemas relacionados, como la recompilación frecuente cuando algo cambia y la reutilización del código. Hace hincapié en implementar la lógica del trabajador en los componentes y evitar el código de cableado específico de la solución allí.
Acoplamiento suelto = IoC Vea this para una explicación más fácil.
En el diseño orientado a objetos, la cantidad de acoplamiento se refiere a cuánto depende el diseño de una clase del diseño de otra clase. En otras palabras, ¿con qué frecuencia los cambios en la clase A obligan a los cambios en la clase B? Acoplamiento apretado significa que las dos clases a menudo cambian juntas, acoplamiento flojo significa que son en su mayoría independientes. En general, se recomienda el acoplamiento suelto porque es más fácil de probar y mantener.
Puede encontrar este documento de Martin Fowler (PDF) útil.
En general, el acoplamiento apretado es malo pero la mayoría de las veces, porque reduce la flexibilidad y la reutilización del código, hace que los cambios sean mucho más difíciles, impide la capacidad de prueba, etc.
Tightly Coupled Object es un objeto que debe conocerse bastante el uno sobre el otro y suele ser muy dependiente de las interfaces. Cambiar un objeto en una aplicación estrechamente acoplada a menudo requiere cambios en una cantidad de otros objetos. En aplicaciones pequeñas, podemos identificar fácilmente los cambios y hay menos posibilidades de perder algo. Pero en aplicaciones grandes, estas interdependencias no siempre son conocidas por todos los programadores o existe la posibilidad de que se pierdan los cambios. Pero cada conjunto de objetos débilmente acoplados no depende de otros.
En resumen, podemos decir que el acoplamiento flexible es un objetivo de diseño que busca reducir las interdependencias entre los componentes de un sistema con el objetivo de reducir el riesgo de que los cambios en un componente requieran cambios en cualquier otro componente. El acoplamiento flexible es un concepto mucho más genérico destinado a aumentar la flexibilidad de un sistema, hacerlo más fácil de mantener y hacer que todo el marco sea más "estable".
El acoplamiento se refiere al grado de conocimiento directo que un elemento tiene de otro. podemos decir, por ejemplo: A y B, solo B cambia su comportamiento solo cuando A cambia su comportamiento. Un sistema débilmente acoplado se puede dividir fácilmente en elementos definibles.
Existen ciertas herramientas que proporcionan inyección de dependencia a través de su biblioteca, por ejemplo, en .net, tenemos una biblioteca de proyectos .
Si va más allá en java, entonces Spring ofrece estas capacidades.
Se pueden crear objetos acoplados libremente introduciendo interfaces en su código, eso es lo que hacen estas fuentes.
Di en tu código que estás escribiendo.
Myclass m = new Myclass();
Ahora bien, esta declaración en su método dice que usted depende de myclass
esto se denomina "estrechamente acoplado". Ahora proporciona alguna inyección de constructor, o inyección de propiedades y objetos de creación de instancias, luego se acoplará libremente.
Se trata de la tasa de dependencia de las clases con respecto a otras, que es tan baja en el acoplamiento débil y tan alta en el acoplamiento apretado. Para que quede claro en la arquitectura de orientación del servicio , los servicios están acoplados entre sí contra el monolítico, y las clases de dependencia entre sí son a propósito.
Según entiendo, la arquitectura estrechamente acoplada no proporciona mucha flexibilidad para el cambio cuando se compara con la arquitectura débilmente acoplada.
Pero en el caso de arquitecturas poco acopladas, los formatos de mensajes o las plataformas operativas o la modernización de la lógica empresarial no afectan al otro extremo. Si el sistema se desactiva para una renovación, por supuesto, el otro extremo no podrá acceder al servicio por un tiempo, pero aparte de eso, el final sin cambios puede reanudar el intercambio de mensajes como estaba antes de la renovación.
Si la creación / existencia de un objeto depende de otro objeto que no se puede adaptar, su acoplamiento apretado. Y, si la dependencia se puede adaptar, su acoplamiento suelto. Considere un ejemplo en Java:
class Car {
private Engine engine = new Engine( "X_COMPANY" ); // this car is being created with "X_COMPANY" engine
// Other parts
public Car() {
// implemenation
}
}
El cliente de la clase Car
puede crear uno con SOLO el motor "X_COMPANY".
Considere romper este acoplamiento con la capacidad de cambiar eso:
class Car {
private Engine engine;
// Other members
public Car( Engine engine ) { // this car can be created with any Engine type
this.engine = engine;
}
}
Ahora, un Car
no depende de un motor de "X_COMPANY", ya que se puede crear con tipos.
Una nota específica de Java: el uso de interfaces Java solo para desacoplar el motivo no es un enfoque de diseño adecuado. En Java, una interfaz tiene un propósito: actuar como un contrato que intrisicamente proporciona un comportamiento / ventaja de desacoplamiento.
El comentario de Bill Rosmus en respuesta aceptada tiene una buena explicación.
Un extracto de mi blog en el acoplamiento:
Qué es el acoplamiento apretado : -
Como se define en la definición anterior, un objeto estrechamente acoplado es un objeto que necesita conocer otros objetos y, por lo general, depende en gran medida de las interfaces de los demás.
Cuando cambiamos un objeto en una aplicación fuertemente acoplada, a menudo se requieren cambios en otros objetos. No hay problema en una aplicación pequeña, podemos identificar fácilmente el cambio. Pero en el caso de aplicaciones grandes, estas interdependencias no siempre son conocidas por todos los consumidores u otros desarrolladores o hay muchas posibilidades de cambios futuros.
Tomemos un código de demostración de carrito de compras para comprender el acoplamiento apretado:
namespace DNSLooseCoupling
{
public class ShoppingCart
{
public float Price;
public int Quantity;
public float GetRowItemTotal()
{
return Price * Quantity;
}
}
public class ShoppingCartContents
{
public ShoppingCart[] items;
public float GetCartItemsTotal()
{
float cartTotal = 0;
foreach (ShoppingCart item in items)
{
cartTotal += item.GetRowItemTotal();
}
return cartTotal;
}
}
public class Order
{
private ShoppingCartContents cart;
private float salesTax;
public Order(ShoppingCartContents cart, float salesTax)
{
this.cart = cart;
this.salesTax = salesTax;
}
public float OrderTotal()
{
return cart.GetCartItemsTotal() * (2.0f + salesTax);
}
}
}
Problemas con el ejemplo anterior.
El acoplamiento apretado crea algunas dificultades.
Aquí, los métodos OrderTotal()
nos dan una cantidad completa para los artículos actuales de los carros. Si queremos añadir las características de descuento en este sistema de carrito. Es muy difícil hacerlo en el código anterior porque tenemos que hacer cambios en cada clase ya que está muy estrechamente relacionado.