Весняний РОЗПРОДАЖ

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

Також відомий як: 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 {
  // ...
  public function __construct($type) {
   $this->type = $type;
  }
  // ...
}
Після
class Employee {
  // ...
  static public function create($type) {
    $employee = new Employee($type);
    // do some heavy lifting.
    return $employee;
  }
  // ...
}
До
class Employee {
  constructor(type: number) {
    this.type = type;
  }
  // ...
}
Після
class Employee {
  static create(type: number): Employee {
    let employee = new Employee(type);
    // Do some heavy lifting.
    return employee;
  }
  // ...
}

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

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

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

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

Переваги

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

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

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

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

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

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

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

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