Logotipo do ConstructiCat
CodeBust.
Explorar a seção ▾

Mudar Associação Unidirecional para Bidirecional.

Problema

Você tem duas classes que precisam, cada uma, usar os recursos da outra, mas a associação entre elas é apenas unidirecional.

Solução

Adicione a associação que falta à classe que precisa dela.

##Exemplo

Antes
class Order {
  Customer customer;

  void setCustomer(Customer arg) {
    customer = arg;
  }
}
class Customer {
}
Depois
class Order {
  Customer customer;

  void setCustomer(Customer arg) {
    if (customer != null) customer.friendOrders().remove(this);
    customer = arg;
    if (customer != null) customer.friendOrders().add(this);
  }
}
class Customer {
  private Set<Order> orders = new HashSet<>();

  Set<Order> friendOrders() {
    return orders;
  }
}

##Por que refatorar

Originalmente, as classes tinham uma associação unidirecional. Mas, com o tempo, o código cliente precisou de acesso aos dois lados da associação.

##Benefícios

  • Se uma classe precisa de uma associação reversa, você pode simplesmente calculá-la. Mas se esses cálculos forem complexos, é melhor manter a associação reversa.

##Como refatorar

  1. Adicione um campo para armazenar a associação reversa.

  2. Decida qual classe será “dominante”. Essa classe conterá os métodos que criam ou atualizam a associação à medida que elementos são adicionados ou alterados, estabelecendo a associação em sua própria classe e chamando os métodos utilitários para estabelecer a associação no objeto associado.

  3. Crie um método utilitário para estabelecer a associação na classe “não dominante”. O método deve usar o que recebe nos parâmetros para preencher o campo. Dê ao método um nome óbvio para que ele não seja usado depois para qualquer outra finalidade.

  4. Se os métodos antigos para controlar a associação unidirecional estavam na classe “dominante”, complemente-os com chamadas aos métodos utilitários do objeto associado.

  5. Se os métodos antigos para controlar a associação estavam na classe “não dominante”, crie os métodos na classe “dominante”, chame-os e delegue a execução a eles.