Autumn SALE

Підйом тіла конструктора

Також відомий як: Pull Up Constructor Body

Проблема

Підкласи мають конструктори з переважно однаковим кодом.

Рішення

Створіть конструктор в суперкласі і винесіть в нього спільний для підкласів код. Викликайте конструктор суперкласу в конструкторах підкласу.

До
class Manager extends Employee {
  public Manager(String name, String id, int grade) {
    this.name = name;
    this.id = id;
    this.grade = grade;
  }
  // ...
}
Після
class Manager extends Employee {
  public Manager(String name, String id, int grade) {
    super(name, id);
    this.grade = grade;
  }
  // ...
}
До
public class Manager: Employee 
{
  public Manager(string name, string id, int grade) 
  {
    this.name = name;
    this.id = id;
    this.grade = grade;
  }
  // ...
}
Після
public class Manager: Employee 
{
  public Manager(string name, string id, int grade): base(name, id)
  {
    this.grade = grade;
  }
  // ...
}
До
class Manager extends Employee {
  public function __construct($name, $id, $grade) {
    $this->name = $name;
    $this->id = $id;
    $this->grade = $grade;
  }
  // ...
}
Після
class Manager extends Employee {
  public function __construct($name, $id, $grade) {
    parent::__construct($name, $id);
    $this->grade = $grade;
  }
  // ...
}
До
class Manager(Employee):
    def __init__(self, name, id, grade):
        self.name = name
        self.id = id
        self.grade = grade
    # ...
Після
class Manager(Employee):
    def __init__(self, name, id, grade):
        Employee.__init__(name, id)
        self.grade = grade
    # ...
До
class Manager extends Employee {
  constructor(name: string, id: string, grade: number) {
    this.name = name;
    this.id = id;
    this.grade = grade;
  }
  // ...
}
Після
class Manager extends Employee {
  constructor(name: string, id: string, grade: number) {
    super(name, id);
    this.grade = grade;
  }
  // ...
}

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

Чим цей рефакторинг відрізняється від підйому методу?

  1. У Java підкласи не можуть наслідувати конструктор, тому ви не можете просто застосувати підйом методу до конструктора підкласу і видалити його після переміщення усього коду конструктора в суперклас. На додаток до створення конструктора в суперкласі треба буде мати конструктори в підкласах з простим делегуванням до конструктора суперкласу.

  2. В C++ і Java (у разі, якщо ви явно не викликали конструктор суперкласу) конструктор суперкласу автоматично викликається перед конструктором підкласу, що робить обов’язковим переміщення спільного коду тільки з початку конструкторів підкласів (оскільки ви не зможете викликати конструктор суперкласу в довільному місці конструктора підкласу).

  3. У більшості мов програмування конструктор підкласу може мати свій власний список параметрів, відмінний від параметрів суперкласу, тому ви повинні створити конструктор суперкласу тільки з тими параметрами, які йому дійсно потрібні.

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

  1. Створіть конструктор в суперкласі.

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

  3. Розташуйте виклик конструктора суперкласу першим рядком в конструкторах підкласів.