Також відомий як Self Encapsulate Field

Рефакторинг Самоінкапсуляція поля

Самоінкапсуляція відрізняється від звичайної «інкапсуляції поля» (Encapsulate field) тим, що рефакторинг робиться над приватним полем.

Проблема

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

Рішення

Створіть геттер і сеттер для поля, і користуйтеся для доступу до поля тільки ними.
До
class Range {
  private int low, high;
  boolean includes(int arg) {
    return arg >= low && arg <= high;
  }
}
Після
class Range {
  private int low, high;
  boolean includes(int arg) {
    return arg >= getLow() && arg <= getHigh();
  }
  int getLow() {
    return low;
  }
  int getHigh() {
    return high;
  }
}
До
class Range 
{
  private int low, high;
  
  bool Includes(int arg) 
  {
    return arg >= low && arg <= high;
  }
}
Після
class Range 
{
  private int low, high;
  
  int Low {
    get { return low; }
  }
  int High {
    get { return high; }
  }
  
  bool Includes(int arg) 
  {
    return arg >= Low && arg <= High;
  }
}
До
private $low;
private $high;

function includes($arg) {
  return $arg >= $this->low && $arg <= $this->high;
}
Після
private $low;
private $high;

function includes($arg) {
  return $arg >= $this->getLow() && $arg <= $this->getHigh();
}
function getLow() {
  return $this->low;
}
function getHigh() {
  return $this->high;
}

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

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

Переваги

  • Непрямий доступ до полів — це коли робота з полем відбувається через методи доступу (геттери і сеттери). Цей підхід відрізняється набагато більшою гнучкістю, ніж прямий доступ до полів.

    • По-перше, ви можете здійснювати складні операції при отриманні або установці даних в полі. Лінива ініціалізація, валідація значень в полі — усе це легко реалізується всередині геттерів і сеттерів поля.

    • По-друге, що ще важливіше, ви можете перевизначати геттери і сеттери в підкласах.

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

Недоліки

  • Коли використовується прямий доступ до полів, код виглядає простіше і наочніше, хоча і втрачає в гнучкості.

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

  1. Створіть геттер (і, опціонально, сеттер) для поля. Вони мають бути захищеними (protected) або публічними (public).

  2. Знайдіть усі прямі звернення до поля і замініть їх викликами геттера і сеттера.

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

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

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

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

Живий приклад

Перший раз у нас? Нічого страшного!

У нас тут все просто – цей інтерактивний приклад дуже схожий на відео (хоча й виглядає набагато крутіше).

  1. Натискаєте велику кнопку "Почати", а далі слідуєте усім підказкам.
  2. Ви можете перемотувати програвання, використовуючи стрілки зліва.
  3. Окрім того, ви можете подивитися різницю між стартовим та отриманим кодом, натиснувши кнопку ока ().
  4. Кнопка компіляції та тестування () дає змогу перевірити код на наявність помилок.