quinta-feira, junho 21, 2007

Um bom sistema possui uma estrutura de classes com baixo acoplamento e alta coesão

Quando nos referimos a um sistema de classes com baixo acoplamento estamos medindo a interligação entre diferentes classes em um sistema [12 pág. 18], ou seja, quanto uma classe conhece e dependente de outra. Classes com baixo acoplamento são mais fáceis de serem entendidas, testadas, reusadas e mantidas, porque podem ser isoladas e trabalhadas individualmente. Além de todas as vantagens, um sistema com classes de baixo acoplamento promove o paralelismo na implementação do sistema, diminuindo o tempo de desenvolvimento e aumenta a produtividade da equipe.

Por outro lado, um caso extremo de baixo acoplamento é quando não existe ou existe muito pouco acoplamento entre as classes. Isso não é desejável porque uma metáfora central da tecnologia de objetos é um sistema composto de objetos conectados que se comunicam através de mensagens. Se o acoplamento baixo é aplicado em excesso, leva a um projeto fraco, porque conduz a uns poucos objetos ativos, sem coesão, inchados e complexos que efetuam todo trabalho. Ao mesmo tempo existirão muitos objetos praticamente passivos, com acoplamento zero, que funcionem como simples repositórios de dados.

Já quando falamos em coesão estamos medindo o quão relacionadas ou focadas estão as responsabilidades da classe [12 pág. 19]. Uma classe com baixa coesão assume responsabilidades que pertencem a outro contexto, com isso torna-se mais difícil de ser entendida, reusada e mantida. Classes de coesão baixa representam, geralmente, uma abstração de grande granularidade ou, então, assumiriam responsabilidades que deveriam ter sido delegadas a outros objetos.

Grady Booch descreve a coesão funcional alta como algo que existe quando os elementos de um componente (tal como uma classe) “trabalham todos em conjunto, para fornecer algum comportamento bem-delimitado” [14].

Uma série de benefícios é relacionada com a coesão alta, como a clareza e a facilidade de compreensão do projeto aumenta, a manutenção e as melhorias são simplificadas, freqüentemente o baixo acoplamento é favorecido, e a granularidade de funcionalidades altamente relacionadas suporta o aumento do potencial de reutilização, porque uma classe altamente coesiva pode ser usada para uma finalidade muito especifica.

Como exemplo, considere o seguinte diagrama de classe parcial de uma aplicação de venda. Suponha que necessitamos criar uma instância de Pagamento de associá-la a Venda.


Qual classe deveria ser responsável por criar Pagamento? Se a classe POST for responsável em criar o Pagamento, a instância de POST poderia, então, enviar uma mensagem acrescentar pagamento para Venda, passando junto um novo Pagamento como parâmetro

Esta atribuição de responsabilidade acopla a classe POST a conhecimento da classe Pagamento. Neste exemplo isolado, isso é aceitável, porém se continuarmos a fazer a classe POST responsável por realizar algum trabalho ou a maior parte dele, o qual esta relacionada cada vez mais operações do sistema, ela se tornará progressivamente mais carregada com tarefas e perderá sua coesão e conseqüentemente o acoplamento será desfavorecido.

Uma solução alternativa para criar Pagamento e associá-lo à Venda é mostrada na próxima figura:

No que diz respeito ao acoplamento, o segundo exemplo ilustrado é preferível porque é mantido um acoplamento geral mais fraco. Sob o ponto de vista da coesão o segundo exemplo favorece uma coesão mais alta em POST.

Por fim, tanto o acoplamento baixo como a coesão alta são princípios a serem levados em conta em todas a decisões do projeto como padrões de avaliação, ou seja, padrões que um projetista avalia em todas as decisões de projeto.