C# - Acoplamento entre classes : herança x composição
Hoje vamos recordar o que é o acoplamento entre classes e quais são os seus efeitos em um projeto de software.

O acoplamento
é a medida de quão interconectadas estão as classes e os subsistemas de um projeto de software.

Assim, o acoplamento é o nível de dependência/conhecimento que pode existir entre os módulos/classes do sistema e

Existem dois tipos de acoplamento:

1 - Acoplamento forte
2 - Acoplamento fraco

Podemos dizer que:

  • Uma classe com acoplamento fraco não é dependente de muitas classes para fazer o que ele tem que fazer;
  • Uma classe com acoplamento forte depende de muitas outras classes para fazer o seu serviço;
  • Uma classe com acoplamento forte é mais difícil de manter, de entender e de ser reusada;

Usar código fracamente acoplado possui as seguintes vantagens

- Um módulo não quebra outros módulos;
- Melhora a testabilidade;
- O código é mais fácil de manter;
- Fica menos afetado por alterações em outros componentes;

Um código fortemente acoplado indica que as classes e os objetos são dependentes um do outro e, portanto, reduzem a reutilização do código.

Assim o acoplamento fraco é preferido, uma vez que alterar uma classe não afetará outra. Ele Reduz dependências em uma classe e isso significa que essa abrodagem facilita a reutilização de código.

Selecionando os principais tipos de relacionamento entre classes que são usados no dia a dia podemos destacar a herança, a composição e o agregação.

Herança e Composição

A herança e a composição são dois dos principais mecanismos para reutilizar funcionalidade e por isso vamos nos ater a eles.

A herança causa um forte acoplamento entre as classes enquanto a composição o acoplamento é mais fraco. Assim devemos dar preferência para a composição e usar herança somente quando for totalmente indicado

Mas porque devemos dar preferência ao usar a composição ao invés da herança ?

Usando herança:

1- Ao usar herança estamos violando um dos pilares da orientação a objetos: o encapsulamento, visto que os detalhes da implementação da classe Pai são expostos nas classes Filhas;
2- Ao usar herança estamos violando um dos princípios básicos das boas práticas de programação : manter o acoplamento entre as classe fraco, visto que as classes filhas estão fortemente acopladas à classe Pai e alterar uma classe Pai pode afetar todas as classes Filhas;
3- As implementações herdadas da classe Pai pelas classes Filhas não pode ser alteradas em tempo de execução;

Usando composição:

1- Os objetos que foram instanciados e estão contidos na classe que os instanciou são acessados somente através de sua interface;
2- A composição pode ser definida dinamicamente em tempo de execução pela obtenção de referência de objetos a objetos de do mesmo tipo;
3- A composição apresenta uma menor dependência de implementações;
4- Na composição temos cada classe focada em apenas uma tarefa (princípio SRP);
5- Na composição temos um bom encapsulamento visto que os detalhes internos dos objetos instanciados não são visíveis;

Percebemos que a herança viola dois conceitos básicos que sempre devemos aplicar em nosso código enquanto que a composição naturalmente nos leva a usar tais conceitos.

Assim considere a utilização da herança se...:

1- A classe Filha expressar "um tipo especial de" e não "ser um papel desempenhado por";
2- Uma instância de uma classe Filha NUNCA precisar tornar-se um objeto de outra classe;
3- A classe filha estender ao invés de substituir total ou parcialmente as responsabilidades da classe Pai;
4- A sua hierarquia de herança representar um relacionamento "É um" e não um relacionamento "Tem um";
5- Você desejar ou precisar realizar alterações globais para as suas classes filhas alterando uma classe Pai;
6- Você precisar aplicar a mesma classe e métodos a diferente tipos de dados;

Na próxima parte do artigo veremos um exemplo prático comparando herança e composição.

"Os meus olhos estão continuamente no Senhor, pois ele tirará os meus pés da rede."
Salmos 25:15

Referências:


José Carlos Macoratti