Associação Bidirecional no Diagrama de Classe


Ultimamente tenho escutado de um colega de trabalho a frase “O óbvio tem que ser dito”, quando ele descobre essas frases ele repeti até cansar. Pensando nessa frase que tanto escuto por esses dias, pensei em falar de uma tipo de associação de classes da UML. Esse tipo associação que me refiro é a Bidirecional, que na verdade é um par de propriedades inversamente vinculadas. Onde por exemplo a classe Carro tem a propriedade Proprietario:Pessoa[1] e a classe Pessoa tem uma propriedade Carros:Carro[*]. Notem que propriedade Carros está de fato no plural para expressar de forma explícita a multiplicidade, uma convenção comum, mas não normativa. O vínculo inverso entre elas significa que, se você seguir duas propriedades, deverá retornar a um conjunto que contém seu ponto inicial – ou de partida. Por exemplo, se eu começar com um Toyota Corolla particular, encontrar seu proprietário e depois ver os carros de seu proprietário, esse conjunto deverá conter o mesmo Toyota Corolla a partir do que comecei.

Como uma alternativa à denominação de uma associação por meio de ma propriedade, muitas pessoas, particularmente se tiverem experiência em modelagem de dados, gostam de rotular uma associação utilizando um verbo para que o relacionamento poos ser usado em uma frase. Isso é valido e você pode adicionar uma seta na associação para evitar ambiguidade. A maioria dos modeladores de objeto prefere utilizar um nome de uma propriedade, pois isso corresponde melhor às responsabilidades e operações. Algumas pessoas nomeiam cada associação de uma certa forma, eu prefiro nomear uma associação somente quando isso melhorar o entendimento. Existem casos que alguns modeladores nomeiam algumas associações com “Tem” Has… ou “Está relacionado a” IsLinkedAs. Abaixo ilustro uma implementação interessante do exemplo do Carro com Proprietário que citei acima.

Classe Carro:

public class Carro {

private Pessoa proprietario;

public Pessoa Proprietario {
   get { return proprietario; }
   set { 
         if (proprietario != null) {
            proprietario.GetCarros().Remove(this);
         }

         proprietario = value;

         if (proprietario != null) {
            proprietario.GetCarros().Add(this);
         }

    } 

}

Classe Pessoa (Proprietário).

public class Pessoa {

   private IList carros = new ArrayList();

   public IList Carros {
      get { return ArrayList.ReadOnly(carros); }
   }

   public void AddCarro(Carro carro) {
      carro.Proprietario = this;
   }

   internal IList GetCarros() {
      // Só pode ser utilizado por Carro.Proprietario.
      return carros;
   }

}

Diagrama de classe ilustrativo sem visão de navegabilidade:

Diagrama de classe ilustrativo com visão de navegabilidade, o que prefiro veemente:

Fiz essa implementação para que notem a importância de compreendermos de fato o vínculo entre as classes e sua navegabilidade. Relacionamento de classes na modelagem orientada a objeto é muito mais que apenas reflexo de um banco de dados relacional. Uma modelagem e desenvolvimento em alto nível de abstração começa quando paramos de pensar em relacional e entendemos o ciclo de vida das entidades, seus relacionamentos, navegabilidade, responsabilidades, identidade e etc. Até +

Leave a comment