Eu tenho um exame de padrões de software esta semana e um dos tópicos que vamos estudar é o acoplamento eferente e aferente.
Entendo que um pacote tenha um Ce alto (acoplamento eferente) se depender de vários outros tipos.
Por exemplo:
class Car{
Engine engine;
Wheel wheel;
Body body;
}
Esta classe teria um acoplamento eferente alto porque depende do tipo de motor, roda e carroçaria.
Enquanto o tipo "roda" teria um alto Ca (acoplamento aferente) se vários outros pacotes dependessem dele (carro, avião, bicicleta).
Uma das perguntas possíveis em nosso exame é: quando o acoplamento eferente / aferente é bom ou ruim? Isso me parece estranho, porque logicamente um programa precisaria de pacotes / classes com alto acoplamento eferente / aferente.
Alguém tem um exemplo de quando / onde o acoplamento eferente ou aferente alto é bom / ruim?
Obrigado !
fonte
Respostas:
O acoplamento aferente pode ser mais facilmente avaliado em termos de quanta dor causa / economiza devido à necessidade ou probabilidade de mudança. Por exemplo, faça sua classe de roda e digamos que muitos outros módulos a usem para construir vários tipos de veículos. Se a classe de roda é extremamente estável, esse acoplamento aferente é benéfico, pois os veículos precisam de rodas e estão usando um confiável. Se, por outro lado, a classe de roda for volátil em termos de manutenção, esse acoplamento aferente será um problema, pois você introduzirá mudanças de interrupção repetidamente em muitos códigos.
O acoplamento eferente é semelhante em conceito, mas você verá uma proposta de valor ligeiramente diferente. Se você tem uma classe de carro que depende diretamente de muitas partes individuais (em vez de dizer apenas "Motor" e "Chassi", e elas consistem em outras sub-partes), a classe provavelmente faz muito e pode, portanto, ser uma gargalo de manutenção. Mudanças nessa classe provavelmente serão difíceis e arriscadas devido à sua complexidade. Por outro lado, se o acoplamento eferente for alto, mas na verdade for bastante coeso e claro, você não terá uma hierarquia de objetos e relacionamentos com os quais se preocupar.
Quando se trata de arquitetura / design, o que você realmente deve considerar são trocas infinitas e essas métricas não são diferentes. Se você quiser descobrir um exemplo de algo ser bom ou ruim, jogue o jogo "what if". Imagine um exemplo e diga "e se eu quisesse fazer X - quanto isso seria péssimo?" Para X, onde a resposta é "muita", você tem uma desvantagem e, para X, onde a resposta é "que seria realmente muito fácil", você tem uma vantagem.
fonte
Falando em generalidades, acoplamento solto:
positivo : protege uma parte do sistema de alterações em algo de que depende (acoplamento aferente)
negativo : o relacionamento pode ser mais difícil de entender
Por exemplo, se eu estivesse desenvolvendo um sistema que dependesse de HTTTP, eu decidiria se preciso acoplar forte ou frouxamente ao HTTP. Se eu pensasse que o sistema provavelmente mudaria para um protocolo diferente, posso optar por associá-lo livremente, enquanto que se eu aceitasse que o HTTP era meu protocolo, poderia associá-lo firmemente a esse protocolo para simplificar o entendimento.
Considere que algumas das complexidades do WS * estão na sua dissociação do HTTP como um protocolo.
fonte
Aferente
Se algo usa um monte de coisas diferentes (alto número de acoplamentos aferentes), é provável que ele se quebre se alguma dessas coisas mudar.
Instabilidade = 1
Eferente
Se algo é usado por um monte de coisas diferentes (alto número de acoplamentos eferentes), então pode haver uma tendência a quebrar muitas coisas se mudar.
Instabilidade = 0
Estabilidade
A definição de Martin de "estabilidade" é uma mistura exótica entre "difícil de mudar" e "com poucas razões para mudar". No entanto, sua métrica de instabilidade descreve apenas "dificuldade de mudança". Os "motivos para mudar" terão muito mais a ver com fatores que não podem ser facilmente calculados, como apenas projetar suas interfaces adequadamente, em um nível apropriado de abstração e entender os requisitos do usuário com mais clareza.
Então, um acoplamento eferente alto com um acoplamento aferente baixo produz estabilidade (como em algo difícil de mudar, pois isso quebra um monte de coisas), o oposto gera instabilidade (como em algo fácil de mudar, pois não quebra um monte de coisas) .
Um grande número de acoplamentos aferentes pode ser um indicador de que seu projeto não tem foco - ele está usando um monte de coisas diferentes, então talvez não tenha uma responsabilidade clara e singular.
Um grande número de acoplamentos eferentes poderia inicialmente ser interpretado como algo realmente bom, pois indica que seu projeto está sendo amplamente (re) utilizado. No entanto, isso seria ruim se você se sentir tentado a mudar o design com frequência, de maneira a quebrar tudo. Portanto, com um grande número de acoplamentos eferentes, é necessário que esses pacotes tenham "poucas ou nenhuma razão para mudar". Os projetos devem ser estáveis no sentido ideal de não ter motivos para mudar, pois também serão muito difíceis de mudar.
Princípio de abstrações estáveis
Conceitos como inversão de dependência (que naturalmente exige injeção de dependência) e SAP (princípio de abstrações estáveis) sugerem que as dependências fluem para abstrações. E há uma razão simples para considerar a "estabilidade" no contexto de "poucas razões para mudar". Uma interface abstrata não menciona detalhes concretos, concentra-se apenas em "o que fazer" em vez de "o que as coisas são" e, portanto, tem menos razões para mudar. A porta gráfica acelerada em nossas placas-mãe (interface abstrata) tem menos motivos para sofrer uma alteração no design do que a GPU que se conecta a ela (um detalhe concreto).
Reutilização x Reutilização
Um tipo de métrica pessoal, se eu puder sugerir uma que colidir um pouco com a de Martin, é essa noção que gosto de insistir em que as bibliotecas mais reutilizáveis devem procurar reutilizar minimamente outro código. Isso leva a instabilidade a um valor zero. É pelos motivos práticos de ter motivos mínimos para mudar, mas também para promover a biblioteca mais fácil de implantar. Uma biblioteca de uso geral e amplamente usada, que depende de uma dúzia de bibliotecas diferentes, tem muitos motivos para mudar, além de uma distribuição de pacotes desajeitados que pode ser difícil de implantar. A diferença aqui é que "razões para mudar", no meu caso, se estendem até a implementação, pois é proveniente de uma visão orientada à biblioteca que procura liberar versões estáveis da biblioteca. Martin pode desconsiderar a implementação como uma parte muito separada,
Do ponto de vista da distribuição, a implementação e a interface se confundem para gerar dependências do usuário em uma biblioteca estável ou instável. Do ponto de vista da interface, apenas a interface é usada e os detalhes da implementação associados são completamente separados.
fonte