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

Замі́на констру́ктора фабри́чним ме́тодом (англ. Replace Constructor with Factory Method) - прийом рефакторингу, що дозволяє замінити конструктор методом, який повертає екземпляр класу.

ПроблемаРедагувати

Є складний конструктор (C#), що виконує не тільки просту установку значень полів об'єкту.

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;
  }
  //...
}


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

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

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

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

ПеревагиРедагувати

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

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

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

Допомагає іншим рефакторингамРедагувати

  • Заміна значення посиланням
  • Заміна кодування типу підкласами

Реалізує паттерн проектуванняРедагувати

  • Фабричний метод

Реалізація на JavaРедагувати

До заміни

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;
  }
  //...
}


Реалізація на PHPРедагувати

До заміни

class Employee {
  ...
  function __construct($type) {
   $this->type = $type;
  }
  ...
}


Після заміни

class Employee {
  ...
  static function create($type) {
    $employee = new Employee($type);
    // do some heavy lifting.
    return $employee;
  }
  ...
}


ПосиланняРедагувати