Також відомий як Replace Constructor with Factory Method

Рефакторинг Заміна конструктора фабричним методом

Проблема

У вас є складний конструктор, що робить щось більше, ніж проста установка значень полів об'єкту.

Рішення

Створіть фабричний метод і замініть ним виклики конструктора.

До
class Employee {
  Employee(int type) {
    this.type = type;
  }
  //...
}
Після
class Employee {
  static Employee create(int type) {
    employee = new Employee(type);
    // do some heavy lifting.
    return employee;
  }
  //...
}
До
public class Employee 
{
  public Employee(int type) 
  {
    this.type = type;
  }
  //...
}
Після
public class Employee
{
  public static Employee Create(int type)
  {
    employee = new Employee(type);
    // do some heavy lifting.
    return employee;
  }
  //...
}
До
class Employee {
  ...
  function __construct($type) {
   $this->type = $type;
  }
  ...
}
Після
class Employee {
  ...
  static function create($type) {
    $employee = new Employee($type);
    // do some heavy lifting.
    return $employee;
  }
  ...
}

Причини рефакторингу

Найочевидніша причина застосування цього рефакторингу пов'язана з заміною кодування типу підкласами.

У вас є код, в якому раніше створювався об'єкт, куди передавалося значення кодованого типу. Після застосування рефакторингу з'явилося вже декілька підкласів, з яких треба створювати об'єкти залежно від значення кодованого типу. Змінити оригінальний конструктор так, щоб він повертав об'єкти підкласів, неможливо, тому ми створюємо статичний фабричний метод, який повертатиме об'єкти потрібних класів, після чого він замінює собою усі виклики оригінального конструктора.

Фабричні методи можна використати і в інших ситуаціях, коли можливостей конструкторів виявляється недостатньо. Вони важливі при заміні значення посиланням. Їх можна також застосовувати для завдання різноманітних режимів створення, параметрів і типів, що виходять за рамки числа.

Переваги

  • Фабричний метод не обов'язково повертає об'єкт того класу, в якому він був викликаний. Часто це можуть бути його підкласи, вибирані залежно від аргументів, що подаються в метод.

  • Фабричний метод може мати вдаліше ім'я, яке описує, що і яким чином він повертає, наприклад, Troops::GetCrew(myTank).

  • Фабричний метод може повернути вже створений об'єкт на відміну від конструктора, який завжди створює новий екземпляр.

Порядок рефакторингу

  1. Створіть фабричний метод. Помістіть його в тіло виклику поточного конструктора.

  2. Замініть усі виклики конструктора викликами фабричного методу.

  3. Оголосіть конструктор приватним.

  4. Обстежте код конструктора і спробуйте винести в фабричний метод той код, який не відноситься до безпосереднього конструювання об'єкту поточного класу.

Замучились читати?

Збігайте за подушкою, в нас тут контенту на 7 годин читання.

Або спробуйте наш новий інтерактивний курсу. Він набагато цікавіший за банальний тест.

Дізнатися більше...