# Acoplamento fraco

Em computação e projetos de sistema um sistema com acoplamento fraco é aquele em que cada um dos seus componentes tem ou faz uso de pouco ou nenhum conhecimento das definições de outros componentes separados. As subáreas incluem o acoplamento de classes, interfaces, dados e serviços. Acoplamento fraco é o oposto de acoplamento forte.

## Vantagens e desvantagens

Componentes em um sistema fracamente acoplado podem ser substituídos por implementações alternativas que fornecem os mesmos serviços. Componentes em um sistema fracamente acoplado são menos restritos à mesma plataforma, idioma, sistema operacional ou ambiente de criação.
Se os sistemas são desacoplados no tempo certo, é difícil também fornecer integridade transacional; são necessários protocolos de coordenação adicionais. Replicação de dados através de sistemas diferentes fornece acoplamento fraco(em disponibilidade), mas cria problemas na manutenção da consistência (sincronização de dados).

## Na integração

Acoplamento fraco em sistemas distribuídos e alcançado através do uso de transações, filas fornecidas pelo middleware orientado a mensagens e padrões de interoperabilidade.
Quatro tipos de autonomia, que promovem o baixo acoplamento, são: autonomia de referência, autonomia de tempo, autonomia de formato e autonomia de plataforma.
O acoplamento frouxo é um princípio de arquitetura e um objetivo de design em arquiteturas orientadas a serviços; onze formas de acoplamento frouxo e suas contrapartes de acoplamento apertado estão listadas em:
* conexões físicas via mediador,
* estilo de comunicação assincrona,
* tipos comuns simples apenas no modelo de dados,
* sistema de tipo fraco,
* mensagens centradas em dados e auto-contidas,
* controle distribuído da lógica do processo,
* ligação dinâmica (de consumidores e provedores de serviço),
* independência de plataforma,
* compensação em nível de negócios, em vez de transações em nível de sistema,
* implantação em diferentes momentos,
* atualizações implícitas no controle de versão.
Enterprise Service Bus (ESB) middleware foi inventado para obter um acoplamento fraco em múltiplas dimensões; no entanto, ESBs overengineered e mispositioned também podem ter o efeito contrário e criar acoplamento apertado indesejado e um hotspot arquitetônico central.
A arquitetura orientada a eventos também visa promover o acoplamento flexível.

### Métodos para redução do acoplamento

O acoplamento frouxo de interfaces pode ser aprimorado pela publicação de dados em um formato padrão (como XML ouXML ou JSON).
O acoplamento fraco entre componentes do programa pode ser aprimorado usando tipos de dados padrão em parâmetros. A passagem de tipos ou objetos de dados personalizados exige que os dois componentes tenham conhecimento da definição de dados personalizada.
O acoplamento frouxo de serviços pode ser aprimorado ao reduzir as informações passadas para um serviço para os dados-chave. Por exemplo, um serviço que envia uma carta é mais reutilizável quando apenas o identificador do cliente é passado e o endereço do cliente é obtido dentro do serviço. Isso desacopla serviços porque os serviços não precisam ser chamados em uma ordem específica (por exemplo, GetCustomerAddress, SendLetter).
O acoplamento frouxo de integração de aplicativos em contextos de automação de processos de negócios pode ser aumentado seguindo um modelo de integração de camada de apresentação no qual aplicativos de automação interagem com aplicativos automatizados subjacentes por meio da camada de apresentação ou da interface gráfica com o usuário.

## Na programação

Acoplamento refere-se ao grau de conhecimento direto, que um componente tem de outro. Acoplamento fraco na área de computação é interpretado como o encapsulamento vs. não-encapsulamento.
Um exemplo de acoplamento rígido ocorre quando uma classe dependente contém um ponteiro diretamente para uma classe concreta que fornece o comportamento necessário. A dependência não pode ser substituída ou sua "assinatura" alterada, sem exigir uma alteração na classe dependente. O acoplamento frouxo ocorre quando a classe dependente contém um ponteiro somente para uma interface, que pode ser implementada por uma ou mais classes concretas. A dependência da classe dependente é para um "contrato" especificado pela interface; uma lista definida de métodos e / ou propriedades que as classes de implementação devem fornecer. Qualquer classe que implemente a interface pode, assim, satisfazer a dependência de uma classe dependente sem precisar alterar a classe. Isso permite extensibilidade no design de software; uma nova classe implementando uma interface pode ser escrita para substituir uma dependência atual em algumas ou todas as situações, sem exigir uma mudança na classe dependente; as classes novas e antigas podem ser trocadas livremente. O acoplamento forte não permite isso.
Este é um diagrama UML que ilustra um exemplo de acoplamento fraco entre uma classe dependente e um conjunto de classes concretas, que fornecem o comportamento necessário:
Para comparação, este diagrama ilustra o design alternativo com forte acoplamento entre a classe dependente e um provedor:

### Outras formas

As linguagens de programação de computador que possuem noções de funções como o módulo central (consulte Programação funcional) ou funções como objetos fornecem excelentes exemplos de programação fracamente acoplada. Linguagens funcionais possuem padrões de Continuações, Fechamento ou geradores. Veja Clojure e Lisp como exemplos de linguagens de programação de funções. Linguagens orientadas a objetos como Smalltalk e Ruby possuem blocos de código, enquanto Eiffel possui agentes. A ideia básica é objetivar (encapsular como um objeto) uma função independente de qualquer outro conceito envolvente (por exemplo, desacoplar uma função de objeto de qualquer conhecimento direto do objeto envolvente). Veja Função de primeira classe para mais informações sobre funções como objetos, o que qualifica como uma forma de função de primeira classe
Assim, por exemplo, em uma linguagem orientada a objetos, quando uma função de um objeto é referenciada como um objeto (liberando-o de ter qualquer conhecimento de seu objeto host) o novo objeto de função pode ser passado, armazenado e chamado em um mais tarde. Objetos destinatários (a quem esses objetos funcionais são fornecidos) podem executar com segurança (chamar) a função contida em sua própria conveniência, sem qualquer conhecimento direto do objeto host que a contém. Dessa forma, um programa pode executar cadeias ou grupos de objetos funcionais, embora seja dissociado com segurança de ter qualquer referência direta ao objeto host que o contém.
Números de telefone são um excelente análogo e podem facilmente ilustrar o grau deste desacoplamento.
Por exemplo: Alguma entidade fornece outro com um número de telefone para fazer um trabalho específico. Quando o número é chamado, a entidade que chama está efetivamente dizendo: "Por favor, faça esse trabalho para mim". O desacoplamento ou acoplamento fraco é imediatamente aparente. A entidade que recebe o número a chamar pode não ter conhecimento de onde o número veio (por exemplo, uma referência ao fornecedor do número). Por outro lado, o chamador é dissociado do conhecimento específico de quem está chamando, onde está e de saber como o receptor da chamada opera internamente.
Levando o exemplo um passo adiante, o interlocutor poderia dizer ao destinatário da ligação: "Por favor, faça esse trabalho para mim. Ligue para mim neste número quando tiver terminado." O "número" que está sendo oferecido ao receptor é chamado de "retorno de chamada". Mais uma vez, a natureza fraca do acoplamento ou desacoplado deste objeto funcional é aparente. O receptor do call-back não sabe o que ou quem está sendo chamado. Só sabe que pode fazer a chamada e decide por si quando ligar. Na realidade, o retorno de chamada pode não ser para aquele que forneceu o retorno em primeiro lugar. Este nível de indireção é o que torna os objetos de função uma excelente tecnologia para alcançar programas fracamente acoplados.

### Mensurando os dados do elemento de acoplamento

O grau do acoplamento solto pode ser medido observando o número de alterações nos elementos de dados que podem ocorrer nos sistemas de envio ou recebimento e determinando se os computadores ainda continuarão se comunicando corretamente. Essas alterações incluem itens como:
* A adição de novos elementos de dados para mensagens
* Alterar a ordem dos elementos de dados
* Alterar os nomes dos elementos de dados
* Alterar as estruturas de elementos de dados
* A omissão de elementos de dados

## Veja também

* Acoplamento (ciência da computação)
* Enterprise service bus
* (Interface de programação de computador)
* A lei de Demeter
* Separação de preocupações
* Arquitetura orientada a serviços