O que é "acoplamento solto?" Forneça exemplos

172

Não consigo entender o conceito de "acoplamento solto". Suponho que não ajuda que a palavra "solto" geralmente tenha uma conotação negativa, então sempre esqueço que o acoplamento solto é uma coisa boa .

Alguém mostra algum código "antes" e "depois" (ou pseudocódigo) que ilustra esse conceito?

trebormf
fonte
Não tenho certeza de como isso pode ser divorciado de um idioma específico, porque parte do conceito é como alguém usa um idioma para impedir que as unidades de código se envolvam demais. Também observo que várias das respostas recorrem ao código para ilustrar o conceito.
Onorio Catenacci
11
Discordo completamente, os aspectos práticos podem ser ilustrados de maneira diferente em idiomas diferentes, e isso é especialmente aparente nos idiomas dinâmico versus compilado. Mas o conceito é o mesmo de qualquer maneira.
Owen
Solto vs apertado e acoplamento vs desacoplamento . Seguir junto nem sempre é uma coisa boa, às vezes é bom / às vezes não é bom ... Como devemos ter independência própria, o mesmo acontece com as aulas.
BonCodigo 14/05

Respostas:

180

Considere um aplicativo simples de carrinho de compras que use uma classe CartContents para acompanhar os itens no carrinho de compras e uma classe Order para processar uma compra. O pedido precisa determinar o valor total do conteúdo do carrinho, pode fazer o seguinte:

Exemplo fortemente 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 como o método OrderTotal (e, portanto, a classe Order) depende dos detalhes de implementação das classes CartContents e CartEntry. Se tentássemos alterar essa lógica para permitir descontos, provavelmente precisaríamos alterar todas as três classes. Além disso, se passarmos a usar uma coleção List para acompanhar os itens, teremos que mudar também a classe Order.

Agora, aqui está uma maneira um pouco melhor de fazer a mesma coisa:

Exemplo 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);
    }
}

A lógica específica da implementação do item de linha do carrinho, da coleção ou do pedido do carrinho é restrita apenas a essa classe. Portanto, poderíamos mudar a implementação de qualquer uma dessas classes sem precisar alterar as outras classes. Poderíamos levar essa dissociação ainda mais longe, melhorando o design, introduzindo interfaces, etc., mas acho que você entende o ponto.

Cunha
fonte
Você poderia expandir a resposta introduzindo mais dissociação através da injeção de dependência (embora o construtor deva ser o ideal)?
BAD_SEED
4
@ Cunha, não vejo razão para a Orderter qualquer conhecimento de um Cart. Compras ao vivo e fabricação são dois contextos diferentes. Quando o cliente estiver pronto para pagar, você poderá ter um processo responsável por converter CartEntries em algo significativo para o Order. Dessa forma, a Orderclasse também seria instanciada e usada sem a Cart.
plalx
@Wedge Você poderia reagir ao meu comentário, por favor?
plalx
Bem e simplesmente explicado. Comecei a ver a luz em ".. Observe como o método OrderTotal (e, portanto, a classe Order) depende dos detalhes de implementação das classes CartContents e CartEntry .."
okey_on
Este exemplo é apresentado claramente. No entanto, atualmente, cada vez mais arquitetos concordam que esse estilo excessivamente orientado a objetos é uma prática ruim. Não faz sentido esconder os detalhes da "implementação" de CartEntrye CartContents. Como estes têm um significado perfeitamente claro, eles devem ser simplesmente modelados como dados mortos. em termos de banco de dados, tudo o que é necessário aqui é uma mesaCREATE TABLE entry (price INTEGER, quantity INTEGER)
Jo Então
160

Muitos produtos integrados (principalmente da Apple), como iPods , iPads são um bom exemplo de acoplamento rígido: quando a bateria acabar, você poderá comprar um novo dispositivo porque a bateria está soldada e não se solta, tornando a substituição muito difícil. caro. Um player fracamente acoplado permitiria trocar a bateria sem esforço.

O mesmo vale para o desenvolvimento de software: geralmente (muito) é melhor ter um código fracamente acoplado para facilitar a extensão e a substituição (e tornar as partes individuais mais fáceis de entender). Porém, muito raramente, em circunstâncias especiais, o acoplamento rígido pode ser vantajoso, porque a forte integração de vários módulos permite uma melhor otimização.

Konrad Rudolph
fonte
O acoplamento solto ou apertado é bom? Como decidir implementar acoplamento frouxo ou apertado?
Sreekanth Karumanaghat
2
obrigado por este grande exemplo. i passou muito tempo em outras respostas, mas não vale a pena como esta
alamin
1
Sreekanth Karumanaghat, você prefere gastar menos dinheiro apenas com uma bateria e ter um iPod funcionando novamente ou prefere gastar muito dinheiro com um iPod inteiro?
Koshera
1
@SreekanthKarumanaghat O acoplamento geralmente solto é melhor porque promove a modularidade e, portanto, facilita a manutenção do código. Se você agrupar firmemente suas classes / bibliotecas / código, qualquer pequena alteração feita em uma classe terá que ser implementada em todas as classes que a utilizam.
precisa
56

Vou usar Java como exemplo. Digamos que temos uma classe que se parece com isso:

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

Quando eu ligo para a classe, precisarei fazer algo assim:

ABC abc = new ABC();

abc. doDiskAccess();

Por enquanto, tudo bem. Agora, digamos que eu tenho outra classe que se parece com isso:

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

Parece exatamente o mesmo que o ABC, mas digamos que funcione através da rede em vez de no disco. Então agora vamos escrever um programa como este:

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

Isso funciona, mas é um pouco pesado. Eu poderia simplificar isso com uma interface como esta:

public interface Runnable
{
    public void run();
}

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

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

Agora meu código pode ficar assim:

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

obj.run();

Veja o quanto isso é mais limpo e simples de entender? Acabamos de entender o primeiro princípio básico do acoplamento flexível: abstração. A chave daqui é garantir que ABC e XYZ não dependam de nenhum método ou variável das classes que os chamam. Isso permite que o ABC e o XYZ sejam APIs completamente independentes. Ou, em outras palavras, eles são "dissociados" ou "fracamente acoplados" das classes pai.

Mas e se precisarmos de comunicação entre os dois? Bem, podemos usar abstrações adicionais, como um Modelo de Evento, para garantir que o código pai nunca precise ser associado às APIs que você criou.

64BitBob
fonte
2
Este exemplo ainda tem um nível bastante alto de acoplamento. Agora, em vez de ser acoplado a uma única classe, há duas para escolher. Este exemplo assume que haverá apenas duas implementações "Executáveis" disponíveis. Nesse caso, uma interface nem sequer é necessária.
Owen
Esses métodos nomeados Run * e Do * são um enorme cheiro de código para mim. Você também pode refatorar isso usando IHandleStuff ou IFrobnicateThings. Executável é um termo muito genérico nesse caso.
Wedge
8
Owen, baby dá um passo no meu amigo. Se ele não entende o acoplamento, como ele vai entender o que um padrão de fábrica lhe compra? Este exemplo de código o coloca no caminho certo. A intenção é que ele entenda melhor o problema e compreenda como abstrair a criação dos objetos.
64BitBob
6
Isso seria mais legível se ABC e XYZ fossem renomeados para algo como DiskAccessore NetworkAccessor? Eu não sei no java ...
MusiGenesis 21/10
Ele também usa padrão de design de fábrica? Porque estamos criando novos objetos XYZ ou ABC, dependendo da necessidade.
munmunbb
37

Desculpe, mas "acoplamento flexível" não é um problema de codificação, é um problema de design. O termo "acoplamento solto" está intimamente relacionado ao estado desejável de "alta coesão", sendo oposto, mas complementar.

O acoplamento solto significa simplesmente que elementos de design individuais devem ser construídos para reduzir a quantidade de informações desnecessárias que eles precisam saber sobre outros elementos de design.

A alta coesão é como "acoplamento rígido", mas a alta coesão é um estado no qual os elementos de design que realmente precisam conhecer um ao outro são projetados para que trabalhem juntos de forma limpa e elegante.

O ponto é que alguns elementos de design devem saber detalhes sobre outros elementos de design, portanto devem ser projetados dessa maneira e não acidentalmente. Outros elementos de design não devem saber detalhes sobre outros elementos de design, portanto devem ser projetados dessa maneira, propositalmente, em vez de aleatoriamente.

Implementar isso é deixado como um exercício para o leitor :).

David M. Karr
fonte
33

Código fortemente acoplado depende de uma implementação concreta. Se eu precisar de uma lista de strings no meu código e declaro-a assim (em Java)

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

então eu sou dependente da implementação ArrayList.

Se eu quiser mudar isso para um código pouco acoplado, faço da minha referência um tipo de interface (ou outro resumo).

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

Isso me impede de chamar qualquer método myListespecífico para a implementação ArrayList. Estou limitado apenas aos métodos definidos na interface da lista. Se eu decidir mais tarde que realmente preciso de um LinkedList, só preciso alterar meu código em um local, onde criei a nova Lista, e não em 100 locais em que fiz chamadas para métodos ArrayList.

Obviamente, você pode instanciar um ArrayList usando a primeira declaração e impedir-se de não usar nenhum método que não faça parte da interface List, mas o uso da segunda declaração faz com que o compilador seja honesto.

Bill the Lizard
fonte
Isso dificilmente se relaciona com o que "acoplamento" realmente é . Consulte stackoverflow.com/questions/39946/coupling-and-cohesion para obter boas respostas.
Rogério
@ Rogerio: Eu acho que se relaciona. Talvez você esteja confuso com outras definições de "acoplamento", mas você deve ler Loose coupling . "O acoplamento forte ocorre quando uma classe dependente contém um ponteiro diretamente para uma classe concreta que fornece o comportamento necessário ... O acoplamento fraco ocorre quando a classe dependente contém um ponteiro apenas para uma interface, que pode ser implementada por uma ou várias classes concretas . " No meu exemplo, meu código seria fracamente acoplado a um ArrayList por meio da interface List.
Bill the Lizard
@ Bill: Obrigado pelo link, mas esse artigo parece completamente falso para mim. Parece "reinterpretar" idéias de outro domínio (comportamento organizacional), dando uma definição de "acoplamento flexível" que contradiz a definição específica de software original de Larry Constantine: en.wikipedia.org/wiki/Coupling_(computer_science) .
Rogério
@ Rogerio: O artigo de Constantine foi escrito em 1974. É provável que muitas reinterpretações tenham ocorrido nos últimos 36 anos, mas não acho que o artigo da Wikipedia seja sua fonte. Por exemplo, padrões como Injeção de Dependência dependem de interfaces para afrouxar o acoplamento, como descrevi na minha resposta.
Bill o Lagarto
2
@ Bill: Claro, o trabalho de Constantine no Projeto Estruturado é algo antigo, mas não vejo nenhum motivo para invalidá-lo ou reinterpretá-lo radicalmente. Os conceitos originais de coesão e acoplamento estão no centro do Design Orientado a Objetos, tanto quanto herança e polimorfismo. DI (um artigo melhor é martinfowler.com/articles/injection.html ) é apenas uma técnica para a configuração externa de plug-ins (interfaces abstratas com implementações selecionadas em tempo de execução por meio do código de configuração); outra técnica é o padrão Service Locator. DI e acoplamento são conceitos independentes.
Rogério
26

O grau de diferença entre as respostas aqui mostra por que seria um conceito difícil de entender, mas colocá-lo da maneira mais simples possível:

Para que eu saiba que, se eu jogar uma bola para você, você pode pegá-la, eu realmente não preciso saber quantos anos você tem. Não preciso saber o que você comeu no café da manhã, e realmente não me importo com quem foi sua primeira paixão. Tudo o que preciso saber é que você pode pegar. Se eu sei disso, então não me importo se é você Eu estou jogando uma bola para você ou seu irmão.

Com linguagens não dinâmicas como c # ou Java etc, realizamos isso por meio de interfaces. Então, digamos que temos a seguinte interface:

public ICatcher
{
   public void Catch();
}

E agora vamos dizer que temos as seguintes classes:

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

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

}

Agora, tanto o CatcherA quanto o CatcherB implementam o método Catch, para que o serviço que requer um Catcher possa usar um desses e não dar a mínima para qual deles é. Portanto, um serviço fortemente associado pode instanciar diretamente um

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

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

}

Portanto, o CatchService pode fazer exatamente o que se propôs a fazer, mas usa o CatcherA e sempre utilizará o CatcherA. É codificado, então fica lá até alguém aparecer e refatorá-lo.

Agora vamos usar outra opção, chamada injeção de dependência:

public CatchService
{
   private ICatcher catcher;

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

Portanto, as mensagens que instansiam o CatchService podem fazer o seguinte:

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

ou

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

Isso significa que o serviço Catch não está totalmente acoplado ao CatcherA ou CatcherB.

Existem várias outras estratégias para serviços de acoplamento frouxo como este, como o uso de uma estrutura de IoC etc.

Owen
fonte
1
Gosto mais desse exemplo que os outros, pois esse tipo de coisa acontece no mundo dos negócios no dia a dia. Se a Pessoa da classe for executada, a Class Cat for executada, a Class Dog executada, etc. Seria um programa enorme para detalhar todas as classes executadas. Porém, o uso de uma interface chamada runs, em que cada classe faz a mesma coisa, torna seu programa muito mais flexível e gerenciável. :)
sksallaj
Explicou muito bem, senhor, apenas para esclarecer no último exemplo, você fez isso com injeção de dependência, e o primeiro exemplo também é fracamente acoplado?
Ali Sajid 23/09
Uau, resposta antiga comentada em :). Portanto, a resposta é não, o primeiro exemplo tem uma dependência duro em CatcherA que eles são fortemente acopladas
Owen
23

Você pode pensar em acoplamento (apertado ou solto) como sendo literalmente a quantidade de esforço necessário para separar uma classe específica de sua dependência de outra classe. Por exemplo, se todos os métodos da sua classe tivessem um bloco finalmente final na parte inferior em que você telefonou para o Log4Net para registrar algo, então você diria que sua classe estava fortemente acoplada ao Log4Net. Se sua classe contivesse um método privado chamado LogSomething, que era o único local que chamava o componente Log4Net (e todos os outros métodos chamavam LogSomething), você diria que sua classe estava fracamente acoplada ao Log4Net (porque não demoraria muito esforço para retirar o Log4Net e substituí-lo por outra coisa).

MusiGenesis
fonte
1
Então, "fracamente acoplado" na verdade significa menos dependências? Estou correcto?
user314362
4
Não está realmente relacionado ao número total de dependências de uma determinada classe. O acoplamento (rígido ou flexível) é na verdade uma propriedade do relacionamento entre duas classes. Portanto, você pode ter uma classe que esteja fracamente acoplada a 100 outras classes ou outra classe que esteja fortemente acoplada a apenas duas outras classes (por exemplo).
MusiGenesis
2
Exemplo ruim, eu diria: o que você tem é duplicação de código, não acoplamento rígido. E com uma boa ferramenta de refatoração, essa duplicação pode ser eliminada em segundos.
Rogério
@ Rogerio: provavelmente não é o melhor exemplo. Eu gosto 64BitBobda resposta melhor, eu mesma.
MusiGenesis
12

Definição

Essencialmente, acoplamento é o quanto um determinado objeto ou conjunto de objetos depende de outro objeto ou outro conjunto de objetos para realizar sua tarefa.

Acoplamento alto

Pense em um carro. Para que o motor dê partida, uma chave deve ser inserida na ignição, girada, a gasolina deve estar presente, uma faísca deve ocorrer, os pistões devem disparar e o motor deve ficar vivo. Você poderia dizer que um motor de carro está altamente acoplado a vários outros objetos. É um acoplamento alto, mas não é realmente uma coisa ruim.

Acoplamento solto

Pense em um controle de usuário para uma página da web responsável por permitir que os usuários publiquem, editem e visualizem algum tipo de informação. O controle único pode ser usado para permitir que um usuário publique uma nova informação ou edite uma nova informação. O controle deve poder ser compartilhado entre dois caminhos diferentes - novo e editar. Se o controle for gravado de forma a precisar de algum tipo de dados das páginas que o conterão, você poderá dizer que é muito acoplado. O controle não deve precisar de nada da página do contêiner.

Tom
fonte
7

É um conceito bastante geral, portanto, os exemplos de código não dão uma visão geral.

Um cara aqui no trabalho me disse: "os padrões são como fractais, você pode vê-los quando você aproxima muito o zoom e quando você aproxima o nível da arquitetura".

A leitura da breve página da Wikipedia pode dar uma idéia dessa generalidade:

http://en.wikipedia.org/wiki/Loose_coupling

No que diz respeito a um exemplo de código específico ...

Aqui está um acoplamento flexível com o qual trabalhei recentemente, do material Microsoft.Practices.CompositeUI.

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

Este código está declarando que esta classe tem uma dependência de um CustomizableGridService. Em vez de apenas fazer referência direta à implementação exata do serviço, ele simplesmente afirma que requer ALGUMA implementação desse serviço. Em tempo de execução, o sistema resolve essa dependência.

Se isso não estiver claro, você pode ler uma explicação mais detalhada aqui:

http://en.wikipedia.org/wiki/Dependency_injection

Imagine que ABCCustomizableGridService é a implementação que pretendo conectar aqui.

Se preferir, posso arrancar isso e substituí-lo por XYZCustomizableGridService ou StubCustomizableGridService sem nenhuma alteração na classe com essa dependência.

Se eu tivesse referenciado diretamente o ABCCustomizableGridService, precisaria fazer alterações nessa / essas referências para trocar em outra implementação de serviço.

arroz
fonte
6

O acoplamento tem a ver com dependências entre sistemas, que podem ser módulos de código (funções, arquivos ou classes), ferramentas em um pipeline, processos servidor-cliente e assim por diante. Quanto menos gerais forem as dependências, mais "fortemente acopladas" elas se tornam, pois a alteração de um sistema exigia a alteração dos outros sistemas que dependem dele. A situação ideal é o "acoplamento flexível", onde um sistema pode ser alterado e os sistemas que dependem dele continuarão a funcionar sem modificações.

A maneira geral de obter um acoplamento flexível é através de interfaces bem definidas. Se a interação entre dois sistemas for bem definida e respeitada pelos dois lados, será mais fácil modificar um sistema, garantindo que as convenções não sejam quebradas. Geralmente ocorre na prática que nenhuma interface bem definida é estabelecida, resultando em um projeto desleixado e acoplamento apertado.

Alguns exemplos:

  • A aplicação depende de uma biblioteca. Sob forte acoplamento, o aplicativo quebra nas versões mais recentes da lib. Google para "DLL Hell".

  • O aplicativo cliente lê dados de um servidor. Sob forte acoplamento, as alterações no servidor exigem correções no lado do cliente.

  • Duas classes interagem em uma hierarquia orientada a objetos. Sob acoplamento rígido, as alterações em uma classe exigem que a outra classe seja atualizada para corresponder.

  • Várias ferramentas de linha de comando se comunicam em um canal. Se estiverem fortemente acoplados, as alterações na versão de uma ferramenta de linha de comando causarão erros nas ferramentas que lêem sua saída.

Parappa
fonte
5

O acoplamento refere-se a quão fortemente diferentes classes estão conectadas umas às outras. As classes fortemente acopladas contêm um alto número de interações e dependências.

Classes fracamente acopladas são o oposto, pois suas dependências entre si são reduzidas ao mínimo e, em vez disso, dependem das interfaces públicas bem definidas umas das outras.

Legos, os brinquedos que SNAP juntos seriam considerados fracamente acoplados porque você pode simplesmente juntar as peças e criar o sistema que desejar. No entanto, um quebra-cabeça tem peças que são firmemente acopladas. Você não pode pegar uma peça de um quebra-cabeça (sistema) e encaixá-la em um quebra-cabeça diferente, porque o sistema (quebra-cabeça) depende muito das peças muito específicas que foram construídas especificamente para esse "design" específico. Os legos são construídos de uma maneira mais genérica, para que possam ser usados ​​na sua Lego House ou no meu Lego Alien Man.

Referência: https://megocode3.wordpress.com/2008/02/14/coupling-and-cohesion/

user1263981
fonte
4

Dois componentes são altamente acoplados quando dependem da implementação concreta um do outro.

Suponha que eu tenha esse código em algum lugar de um método na minha classe:

this.some_object = new SomeObject();

Agora, minha classe depende do SomeObject e eles são altamente acoplados. Por outro lado, digamos que eu tenho um método InjectSomeObject:

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

Em seguida, o primeiro exemplo pode apenas usar SomeObject injetado. Isso é útil durante o teste. Com a operação normal, você pode usar classes pesadas, de banco de dados, de rede, etc. Com código fortemente associado, você não pode fazer isso.

Você pode facilitar algumas partes deste trabalho usando contêineres de injeção de dependência. Você pode ler mais sobre o DI na Wikipedia: http://en.wikipedia.org/wiki/Dependency_injection .

Às vezes é fácil levar isso longe demais. Em algum momento, você precisa tornar as coisas concretas, ou seu programa será menos legível e compreensível. Portanto, use essas técnicas principalmente nos limites dos componentes e saiba o que está fazendo. Verifique se você está aproveitando o acoplamento solto. Caso contrário, você provavelmente não precisa disso naquele lugar. O DI pode tornar seu programa mais complexo. Certifique-se de fazer uma boa troca. Em outras palavras, mantenha um bom equilíbrio. Como sempre, ao projetar sistemas. Boa sorte!

Paweł Hajdan
fonte
3

Considere um aplicativo do Windows com FormA e FormB. FormA é o formulário principal e exibe FormB. Imagine o FormB precisando passar dados de volta para o pai.

Se você fez isso:

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

    ...
    fb.Show();
}

class FormB 
{
    FormA parent;

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

O FormB está firmemente acoplado ao FormA. FormB não pode ter outro pai que não seja do tipo FormA.

Se, por outro lado, o FormB publicasse um evento e o FormA assinasse esse evento, o FormB poderia enviar dados de volta por esse evento para qualquer assinante desse evento. Nesse caso, o FormB nem sabe que está falando com o pai; através do acoplamento solto, o evento oferece apenas conversas com os assinantes. Qualquer tipo agora pode ser pai do FormA.

rp

rp.
fonte
3

Na ciência da computação, existe outro significado para "acoplamento solto" que ninguém mais postou aqui, então ... Aqui vai - espero que você me dê alguns votos para que isso não se perca no fundo da pilha! Certamente o assunto da minha resposta pertence a qualquer resposta abrangente à pergunta ... A saber:

O termo "Loose Coupling" entrou na computação pela primeira vez como um termo usado como adjetivo em relação à arquitetura da CPU em uma configuração de várias CPUs. Seu termo de contrapartida é "acoplamento rígido". O Loose Coupling é quando as CPUs não compartilham muitos recursos em comum e o Tight Coupling é quando o fazem.

O termo "sistema" pode ser confuso aqui; portanto, analise a situação com cuidado.

Normalmente, mas nem sempre, várias CPUs em uma configuração de hardware na qual elas existem em um sistema (como nas caixas individuais de "PC") seriam fortemente acopladas. Com exceção de alguns sistemas de desempenho super alto que possuem subsistemas que realmente compartilham memória principal entre "sistemas", todos os sistemas divisíveis são fracamente acoplados.

Os termos Tightly Coupled e Loosely Coupled foram introduzidos antes da criação de CPUs com vários threads e com vários núcleos; portanto, esses termos podem precisar de alguns companheiros para articular completamente a situação hoje. E, de fato, hoje é possível ter um sistema que engloba ambos os tipos em um sistema geral. Em relação aos sistemas de software atuais, existem duas arquiteturas comuns, uma de cada variedade, que são comuns o suficiente, e devem ser familiares.

Primeiro, como era a questão, alguns exemplos de sistemas Loosely Coupled:

  • VaxClusters
  • Clusters Linux

Por outro lado, alguns exemplos firmemente acoplados:

  • Sistemas operacionais Semetrical-Multi-Processing (SMP) - por exemplo, Fedora 9
  • CPUs multiencadeadas
  • CPUs com vários núcleos

Na computação atual, exemplos de ambos operando em um único sistema geral não são incomuns. Por exemplo, considere as modernas CPUs Pentium, dual ou quad core, executando o Fedora 9 - estes são sistemas de computação fortemente acoplados. Em seguida, combine vários deles em um Linux Cluster fracamente acoplado e agora você terá uma computação acoplado fracamente e fortemente acoplada! Oh, o hardware moderno não é maravilhoso!

Richard T
fonte
3

Em linguagem simples, pouco acoplada significa que não depende de outro evento para ocorrer. Ele executa de forma independente.

Ravindra Miyani
fonte
1
Isso não é verdade - como mencionado em outros exemplos, não se trata muito de saber se existe ou não um relacionamento entre entidades (módulos, classes), mas se elas podem ou não ser facilmente trocadas por outras classes que implementam a mesma funcionalidade. por exemplo, um ViewModel trabalho poder, com diferentes modelos, mas definitivamente não irá funcionar sem um
Hayden Crocker
eh, não muito útil
brgs 18/06/19
2

Algumas respostas longas aqui. O princípio é muito simples. Apresento a declaração de abertura da wikipedia :

"O acoplamento flexível descreve um relacionamento resiliente entre dois ou mais sistemas ou organizações com algum tipo de relacionamento de troca.

Cada extremidade da transação torna seus requisitos explícitos e faz poucas suposições sobre a outra extremidade. "

Ben Aston
fonte
1
Se fosse tão simples, não teríamos essa discussão.
ERS
2

Proponho um teste muito simples de acoplamento de código :

  1. A parte A do código está firmemente acoplada à parte B do código, se houver alguma modificação possível na parte B que forçaria alterações na parte A para manter a correção.

  2. A peça A do código não está firmemente acoplada à peça B do código se não houver uma possível modificação na peça B que faça uma alteração na peça A necessária.

Isso ajudará você a verificar a quantidade de acoplamento entre as partes do seu código. para raciocinar sobre isso, consulte esta postagem no blog: http://marekdec.wordpress.com/2012/11/14/loose-coupling-tight-coupling-decoupling-what-is-that-all-about/

Marek Dec
fonte
2

Ao criar um objeto de uma classe usando a newpalavra-chave em alguma outra classe, você está realmente fazendo um acoplamento rígido (prática recomendada); em vez disso, deve usar um acoplamento flexível, o que é uma boa prática

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

--- MainClass ---

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 

}
}

Explicação:

No exemplo acima, temos duas classes A e B

A classe B implementa Interface, ou seja, InterfaceClass.

InterfaceClass define um Contrato para a classe B, pois InterfaceClass possui métodos abstratos da classe B que podem ser acessados ​​por qualquer outra classe, por exemplo A.

Na classe A, temos o método de exibição que pode, exceto o objeto da classe que implementa InterfaceClass (no nosso caso, é a classe B). E nesse objeto, o método da classe A está chamando display () e getVar () da classe B

No MainClass, criamos o objeto das Classes A e B. E chamamos o método de exibição de A passando o objeto da classe B, ou seja, objb. O método de exibição de A será chamado com o objeto da classe B.

Agora falando sobre acoplamento solto. Suponha que no futuro você precise alterar o nome da Classe B para ABC e não precise alterá-lo no método de exibição da classe B, apenas crie o objeto new (classe ABC) e passe-o para o método de exibição no MailClass. Você não precisa alterar nada na classe A

ref: http://p3lang.com/2013/06/loose-coupling-example-using-interface/

Abhishek Aggarwal
fonte
0

Você pode ler mais sobre o conceito genérico de "acoplamento flexível" .

Em resumo, é uma descrição de um relacionamento entre duas classes, em que cada classe sabe o mínimo sobre a outra e cada classe pode continuar a funcionar muito bem se a outra estiver presente ou não e sem depender da implementação específica da outra. classe.

Franci Penov
fonte
-8

O acoplamento flexível, em geral, é de 2 atores trabalhando independentemente um do outro na mesma carga de trabalho. Portanto, se você tivesse dois servidores da Web usando o mesmo banco de dados de back-end, diria que esses servidores da Web são fracamente acoplados. Um acoplamento rígido seria exemplificado por ter 2 processadores em um servidor da Web ... esses processadores estão fortemente acoplados.

Espero que seja um pouco útil.

Steve
fonte
1
Entendo o que você está buscando, mas ainda não é uma maneira muito boa de explicar que o acoplamento rígido é quando duas "coisas" são interdependentes entre si, em comparação com o acoplamento flexível quando duas "coisas" existem independentemente - onde uma "coisa" pode ser alterado sem alterações para a outra 'coisa' ...
Bryan Rehbein
Steve, você está EXATAMENTE certo - você não mereceu nenhum dos votos negativos. É apenas que seu público não estava pronto para sua terminologia e muitos neste site têm o hábito de votar o que não entendem ou o que não é familiar. -shrug-
Richard T
Eu acho que Steve errou o alvo. O acoplamento frouxo nem sempre implica dois atores trabalhando independentemente na mesma carga de trabalho.
Rob