Самоінкапсуляція поля
Самоінкапсуляція відрізняється від звичайної інкапсуляції поля тим, що рефакторинг робиться над приватним полем.
Проблема
Ви використовуєте прямий доступ до приватних полів усередині класу.
Рішення
Створіть геттер і сеттер для поля, і користуйтеся для доступу до поля тільки ними.
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;
}
class Range {
private low: number
private high: number;
includes(arg: number): boolean {
return arg >= low && arg <= high;
}
}
class Range {
private low: number
private high: number;
includes(arg: number): boolean {
return arg >= getLow() && arg <= getHigh();
}
getLow(): number {
return low;
}
getHigh(): number {
return high;
}
}
Причини рефакторингу
Буває так, що вам перестає вистачати гнучкості з прямим доступом до приватного поля всередині класу. Ви хочете мати можливість ініціалізувати значення поля при першому запиті або робити якісь операції над новими значеннями поля в момент присвоєння, або робити все це різними способами в підкласах.
Переваги
-
Непрямий доступ до полів — це коли робота з полем відбувається через методи доступу (геттери і сеттери). Цей підхід відрізняється набагато більшою гнучкістю, ніж прямий доступ до полів.
-
По-перше, ви можете здійснювати складні операції при отриманні або установці даних в полі. Лінива ініціалізація, валідація значень в полі — усе це легко реалізується всередині геттерів і сеттерів поля.
-
По-друге, що ще важливіше, ви можете перевизначати геттери і сеттери в підкласах.
-
-
Ви можете взагалі не реалізовувати сеттер для поля. Значення поля задаватиметься тільки в конструкторі, роблячи це поле незмінним для всього періоду життя об’єкта.
Недоліки
- Коли використовується прямий доступ до полів, код виглядає простіше і наочніше, хоча і втрачає в гнучкості.
Порядок рефакторингу
-
Створіть геттер (і, опціонально, сеттер) для поля. Вони мають бути захищеними (
protected
) або публічними (public
). -
Знайдіть усі прямі звернення до поля і замініть їх викликами геттера і сеттера.