Також відомий як Self 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 годин читання.

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

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