Логотип ConstructiCat
CodeBust.
Навигация по разделу ▾

Замена однонаправленной связи двунаправленной.

Проблема

У вас есть два класса, которым нужно использовать фичи друг друга, но между ними существует только односторонняя связь.

Решение

Добавьте недостающую связь в класс, в котором она отсутствует.

##Пример

До
class Order {
  Customer customer;

  void setCustomer(Customer arg) {
    customer = arg;
  }
}
class Customer {
}
После
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;
  }
}

##Зачем делать рефакторинг

Между классами изначально была одностороння связь. Однако с течением времени клиентскому коду потребовался доступ в обе стороны этой связи.

##Преимущества

  • Если в классе возникает необходимость в обратной связи, её можно попросту вычислить. Однако, если такие вычисления оказываются довольно сложными, лучше хранить обратную связь.

##Как делать рефакторинг

  1. Добавьте поле, которое будет содержать обратную связь.

  2. Решите, какой класс будет «управляющим». Этот класс должен содержать методы, которые создают или обновляют связь при добавлении или изменении элементов, устанавливая связь в своём классе, а также вызывая служебные методы установки связи в связываемом объекте.

  3. Создайте служебный метод установки связи в «не управляющем классе». Этот метод должен заполнять поле со связью тем, что ему подают в параметрах. Назовите этот метод так, чтобы было очевидно, что его не стоит использовать в других целях.

  4. Если старые методы управления однонаправленной связью находились в «управляющем классе», дополните их вызовами служебных методов из связываемого объекта.

  5. Если старые методы управления связью находились в «не управляющем классе», создайте управляющие методы в «управляющем классе», вызывайте их и делегируйте им выполнение.