Qual é a diferença entre acoplamento solto e acoplamento rígido no paradigma orientado a objects?

Qualquer um pode descrever a diferença exata entre acoplamento fraco e acoplamento firme no paradigma Orientado a objects?

   

O acoplamento apertado é quando um grupo de classs é altamente dependente um do outro.

Esse cenário surge quando uma class assume muitas responsabilidades ou quando uma preocupação é distribuída por muitas classs em vez de ter sua própria class.

O acoplamento frouxo é obtido por meio de um projeto que promove responsabilidade única e separação de interesses.

Uma class fracamente acoplada pode ser consumida e testada independentemente de outras classs (concretas).

As interfaces são uma ferramenta poderosa para o desacoplamento. As classs podem se comunicar por meio de interfaces, em vez de outras classs concretas, e qualquer class pode estar no outro lado da comunicação simplesmente implementando a interface.

Exemplo de acoplamento apertado:

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) { } } 

Exemplo de acoplamento solto:

 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) { } } 

Outro exemplo aqui .

Explicação do conceito sem código

Exemplo de resumo:

O chapéu é “frouxamente acoplado” ao corpo. Isso significa que você pode facilmente tirar o chapéu sem fazer qualquer alteração na pessoa / corpo. Quando você pode fazer isso, então você tem “acoplamento solto”. Veja abaixo para elaboração.

O chapéu é

Acoplamento apertado (exemplo detalhado)

Pense na sua pele. Está preso ao seu corpo. Se encheckbox como uma luva. Mas e se você quisesse mudar sua cor de pele de branco para preto? Você pode imaginar o quão doloroso seria descascar sua pele, tingi-la e depois colá-la de volta? Mudar sua pele é difícil porque está fortemente acoplada ao seu corpo. Você simplesmente não pode fazer alterações facilmente. Você teria que redesenhar fundamentalmente um ser humano para tornar isso possível.

  • Ponto-chave # 1 : Em outras palavras, se você quiser mudar a pele, você também teria que mudar o design do seu corpo , porque os dois estão unidos – eles são fortemente acoplados.

Deus não era um bom programador orientado a objects.

Acoplamento solto (exemplo detalhado)

Agora pense em se vestir de manhã. Você não gosta de azul? Sem problemas: você pode colocar uma camiseta vermelha em vez disso. Você pode fazer isso com facilidade e sem esforço porque a camisa não está realmente conectada ao seu corpo da mesma maneira que a sua pele. A camisa não sabe ou se importa com o corpo que está acontecendo . Em outras palavras, você pode trocar de roupa, sem realmente mudar seu corpo.

  • Esse é o ponto chave # 2. Se você mudar sua camisa, então você não é forçado a mudar seu corpo – quando você pode fazer isso, então você tem o acoplamento solto. Quando você não pode fazer isso, então você tem um acoplamento apertado.

Esse é o conceito básico em poucas palavras.

Por que tudo isso é importante?

É importante porque o software muda o tempo todo. De um modo geral, você deseja poder modificar facilmente seu código.

Por exemplo, exemplos práticos

  • Se alguém quiser sua saída em um arquivo CSV em vez de JSON etc., ou se quiser mudar do MySQL para o PostGreSQL, você poderá fazer essas alterações com extrema facilidade em seu código, sem ter que rewrite toda a class e passar 10 horas debugging. Em outras palavras, você não deseja associar seu aplicativo a uma implementação de database específica (por exemplo, Mysql) ou a uma saída específica (por exemplo, arquivos CSV). Porque, como é inevitável no software, as mudanças virão. Quando eles chegam, é muito mais fácil se suas partes do código estiverem fracamente acopladas.
  • Se alguém quer seu carro em preto , você não deveria ter que reprojetar o carro inteiro para fazer isso. Um carro e suas peças sobressalentes seriam um exemplo perfeito de uma arquitetura fracamente acoplada (conforme os comentários do @mnmopazem). Se você quiser replace seu motor por um melhor, você deve ser capaz de simplesmente remover o seu motor sem muito esforço e trocá-lo por um melhor. Se o seu carro só funciona com motores Rolls Royce ABC2000 e nenhum outro motor – então o seu carro estará fortemente acoplado a esse motor (Rolls Royce ABC200). Seria melhor se você mudasse o design do seu carro para que ele funcionasse com qualquer motor, de modo que ele fosse um pouco mais solto com seus componentes. Ainda melhor seria se o seu carro pudesse funcionar sem precisar de um motor! Alguma quantidade de acoplamento vai acontecer, mas deve-se trabalhar para minimizá-lo o máximo possível, porque quando os requisitos mudam, ainda devemos ser capazes de fornecer software de boa qualidade, muito rapidamente.

Resumo

Em suma, o acoplamento frouxo torna o código mais fácil de mudar. As respostas acima fornecem algum código que vale a pena ler neste momento.

Atribuição de imagem .

No projeto orientado a objects, a quantidade de acoplamento refere-se ao quanto o projeto de uma class depende do projeto de outra class. Em outras palavras, com que frequência as mudanças na class A forçam as mudanças relacionadas na class B? Acoplamento apertado significa que as duas classs freqüentemente mudam juntas, o que significa que elas são, na maior parte, independentes. Em geral, o acoplamento flexível é recomendado porque é mais fácil de testar e manter.

Você pode encontrar este artigo por Martin Fowler (PDF) útil.

Diferença entre o acoplamento apertado e o acoplamento frouxo do programa?

Acoplamento apertado entre objects Java

 class Traveler { Car c=new Car(); void startJourney() { c.move(); } } class Car { void move() { // logic... } } 

Acoplamento Solto entre Objetos Java

 class Traveler { Vehicle v; public void setV(Vehicle v) { this.v = v; } void startJourney() { v.move(); } } 

// ========================= Interface ====================== ==============

  Interface Vehicle { void move(); } 

// ==================== Múltipla class implementa interface de veículo. Primeira aula ====

 class Car implements Vehicle { public void move() { // logic } } 

// =================== Segunda class ================

 class Bike implements Vehicle { public void move() { // logic } } 

Em geral, o acoplamento apertado é ruim, mas na maioria das vezes, porque reduz a flexibilidade e a reutilização do código, torna as alterações muito mais difíceis, impede a testabilidade, etc.

Objeto fortemente acoplado é um object que precisa saber um pouco sobre o outro e geralmente é altamente dependente de outras interfaces. A alteração de um object em um aplicativo fortemente acoplado geralmente requer alterações em vários outros objects. Em aplicativos pequenos, podemos identificar facilmente as alterações e há menos chances de perder alguma coisa. Mas, em aplicações grandes, essas interdependencies nem sempre são conhecidas por todos os programadores, ou a chance existe para perder as mudanças. Mas cada conjunto de objects fracamente acoplados não depende de outros.

Em suma, podemos dizer que o acoplamento flexível é uma meta de design que procura reduzir as interdependencies entre os componentes de um sistema com o objective de reduzir o risco de que alterações em um componente exijam alterações em qualquer outro componente. O acoplamento frouxo é um conceito muito mais genérico destinado a aumentar a flexibilidade de um sistema, torná-lo mais sustentável e tornar a estrutura inteira mais estável.

Acoplamento refere-se ao grau de conhecimento direto que um elemento tem do outro. podemos dizer um exemplo: A e B, somente B muda seu comportamento apenas quando A modifica seu comportamento. Um sistema fracamente acoplado pode ser facilmente decomposto em elementos definíveis.

Quando dois objects são fracamente acoplados, eles podem interagir, mas têm muito pouco conhecimento um do outro.

Projetos de acoplamento frouxo nos permitem construir sistemas OO flexíveis que podem lidar com mudanças.

O padrão de design do observador é um bom exemplo para tornar classs pouco acopladas, você pode dar uma olhada nele na Wikipedia .

A maneira que eu entendo é que a arquitetura fortemente acoplada não oferece muita flexibilidade para a mudança quando comparada à arquitetura fracamente acoplada.

Mas, no caso de arquiteturas fracamente acopladas, formatos de mensagem ou plataformas operacionais ou reformulação da lógica de negócios não afetam a outra extremidade. Se o sistema for retirado para uma reformulação, é claro que a outra extremidade não poderá acessar o serviço por algum tempo, mas fora isso, a finalização inalterada poderá retomar a troca de mensagens como era antes da renovação.

Um extrato do meu post no acoplamento:

O que é acoplamento apertado : –

Como acima definição, um Objeto Muito Acoplado é um object que precisa saber sobre outros objects e geralmente é altamente dependente das interfaces uns dos outros.

Quando alteramos um object em um aplicativo fortemente acoplado, muitas vezes ele exige alterações em vários outros objects. Não há problema em um aplicativo pequeno, podemos identificar facilmente a mudança. Mas, no caso de aplicações grandes, essas interdependencies nem sempre são conhecidas por todos os consumidores ou outros desenvolvedores, ou há muitas chances de mudanças futuras.

Vamos pegar um código de demonstração do carrinho de compras para entender o acoplamento forte:

 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 com o exemplo acima

O acoplamento apertado cria algumas dificuldades.

Aqui, os methods OrderTotal() nos dão um valor total para os itens atuais dos carrinhos. Se quisermos adicionar os resources de desconto neste sistema de carrinho. É muito difícil fazer o código acima porque temos que fazer mudanças em todas as classs, pois é muito acoplado.

Existem certas ferramentas que fornecem injeção de dependência através de sua biblioteca, por exemplo, em .net, temos a biblioteca ninject .

Se você está indo mais longe em java, a primavera fornece esses resources.

Objetos acoplados fracamente podem ser feitos introduzindo Interfaces em seu código, e é o que essas fonts fazem.

Diga em seu código que você está escrevendo

 Myclass m = new Myclass(); 

Agora esta afirmação em seu método diz que você é dependente de myclass isto é chamado de fortemente acoplado. Agora você fornece alguma injeção de construtor, ou injeção de propriedade e object de instanciação, então ele se tornará acoplado fracamente.

Acoplamento solto significa grau de dependência entre dois componentes é muito baixo Ex.GSM SIM Acoplamento apertado significa grau de dependência entre dois componentes é muito alta. ex. CDMA Mobile

O acoplamento frouxo é e responde às dependencies codificadas em estilo antigo e questões relacionadas, como recompilation frequente quando algo muda e reutiliza código. Ele enfatiza a implementação da lógica do trabalhador em componentes e evita o código de conexão específico da solução.

Loose Coupling = IoC Veja isto para uma explicação mais fácil.

Loose Coupling é o processo de dar a dependência que sua class precisa indiretamente, sem fornecer todas as informações da dependência (ou seja, na interface), no caso de acoplamento direto, você fornece diretamente a dependência, o que não é uma boa maneira de codificar.

É sobre a taxa de dependência de classs para outras que é tão baixa em pouco acoplada e tão alta em fortemente acoplada. Para ser claro na arquitetura de orientação a serviços, os serviços são fracamente acoplados uns aos outros contra monolítico, o que é dependente de classs entre si.

Acoplamento apertado significa que uma class depende de outra class. Loose Coupling significa que uma class depende da interface rathar que da class.

No acoplamento apertado, há dependência codificada declarada nos methods. No acoplamento Loose, devemos passar a dependência externamente no tempo de execução em vez do hardcoded (os sistemas Loose Couple são uma interface de uso para diminuir a dependência com a class)

Por exemplo, temos um sistema que pode enviar saída de duas ou mais maneiras, como JSON-Output, CSV-Output etc.

Apertado 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(); } } 

No exemplo acima, se quisermos alterar a saída em JSON, precisaremos encontrar e alterar todo o código, porque a Class1 está bem presa à class CSVOutputGenerator.

Solto 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(); } } 

Se a criação / existência de um object depende de outro object que não pode ser adaptado, seu acoplamento forte. E, se a dependência puder ser adaptada, seu acoplamento solto. Considere um exemplo em Java:

 class Car { private Engine engine = new Engine( "X_COMPANY" ); // this car is being created with "X_COMPANY" engine // Other parts public Car() { // implemenation } } 

O cliente da class Car pode criar um com apenas o mecanismo “X_COMPANY”.

Considere quebrar esse acoplamento com a capacidade de mudar isso:

 class Car { private Engine engine; // Other members public Car( Engine engine ) { // this car can be created with any Engine type this.engine = engine; } } 

Agora, um Car não depende de um mecanismo de “X_COMPANY”, pois ele pode ser criado com tipos.

Uma nota específica do Java: o uso de interfaces Java apenas para o saque de acoplamento não é uma abordagem de design adequada. Em Java, uma interface tem um propósito – atuar como um contrato que fornece, intrinsecamente, comportamento / vantagem de desacoplamento.

O comentário de Bill Rosmus na resposta aceita tem uma boa explicação.