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?
oop
language-agnostic
loose-coupling
trebormf
fonte
fonte
Respostas:
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:
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:
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.
fonte
Order
ter qualquer conhecimento de umCart
. 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 oOrder
. Dessa forma, aOrder
classe também seria instanciada e usada sem aCart
.CartEntry
eCartContents
. 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)
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.
fonte
Vou usar Java como exemplo. Digamos que temos uma classe que se parece com isso:
Quando eu ligo para a classe, precisarei fazer algo assim:
Por enquanto, tudo bem. Agora, digamos que eu tenho outra classe que se parece com isso:
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:
Isso funciona, mas é um pouco pesado. Eu poderia simplificar isso com uma interface como esta:
Agora meu código pode ficar assim:
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.
fonte
DiskAccessor
eNetworkAccessor
? Eu não sei no java ...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 :).
fonte
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)
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).
Isso me impede de chamar qualquer método
myList
especí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.
fonte
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:
E agora vamos dizer que temos as seguintes classes:
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
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:
Portanto, as mensagens que instansiam o CatchService podem fazer o seguinte:
ou
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.
fonte
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).
fonte
64BitBob
da resposta melhor, eu mesma.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.
fonte
É 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.
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.
fonte
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.
fonte
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/
fonte
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:
Agora, minha classe depende do SomeObject e eles são altamente acoplados. Por outro lado, digamos que eu tenho um método InjectSomeObject:
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!
fonte
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:
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
fonte
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:
Por outro lado, alguns exemplos firmemente acoplados:
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!
fonte
Em linguagem simples, pouco acoplada significa que não depende de outro evento para ocorrer. Ele executa de forma independente.
fonte
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. "
fonte
Proponho um teste muito simples de acoplamento de código :
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.
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/
fonte
Ao criar um objeto de uma classe usando a
new
palavra-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 ---
--- B.java ---
--- InterfaceClass ---
--- MainClass ---
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/
fonte
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.
fonte
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.
fonte