Заміна простого поля об'єктом
Проблема
В класі (чи групі класів) є поле простого типу. У цього поля є своя поведінка і пов’язані дані.
Рішення
Створіть новий клас, помістіть в нього старе поле та його поведінку, зберігайте об’єкт цього класу в початковому класі.
Причини рефакторингу
В цілому цей рефакторинг є одним з варіантів рефакторингу відокремлення класу. Відмінності полягають в причинах, які привели до потреби у внесенні змін до коду.
У відокремленні класу ми маємо один клас, який відповідає за різні речі, і хочемо розділити його відповідальність.
У заміні простого поля об’єктом ми маємо поле примітивного типу (число, рядок і ін.), яке з розвитком програми перестало бути таким простим і обзавелося пов’язаними даними і поведінкою. З одного боку, в наявності таких полів немає нічого страшного, з іншого — така сім’я-полей-та-поведінок може знаходитися в декількох класах одночасно, створюючи багато дублюючого коду.
Тому ми створюємо для всього цього новий клас і переносимо в нього не лише саме поле, але і пов’язані з ним дані і поведінку.
Переваги
- Покращує зв’язність усередині класів. Дані і поведінка цих даних знаходяться в одному класі.
Порядок рефакторингу
Перед тим як почати, подивіться чи використовується поле в класі безпосередньо. Якщо так, застосуйте самоінкапсуляцію поля, щоби приховати його в початковому класі.
-
Створіть новий клас і скопіюйте в нього ваше поле і його геттер. Крім того, створіть конструктор, що набуває простого значення цього поля. У цьому класі не буде сеттера, оскільки кожне нове значення поля, що подається в оригінальний клас, створюватиме новий об’єкт-значення.
-
У початковому класі змініть тип поля на новий клас.
-
У його геттері в початковому класі звертайтеся до геттера пов’язаного об’єкта.
-
У сеттері створіть новий об’єкт-значення. Можливо, вам потрібно буде також створити новий об’єкт в конструкторі, якщо раніше там задавалися якісь початкові значення для поля.
Подальші кроки
Після цього рефакторингу іноді має сенс застосувати заміну значення посиланням над полем, що містить об’єкт. Це дозволяє замість зберігання десятків об’єктів для одного і того ж значення поля зберігати посилання на один об’єкт, що відповідає цьому значенню.
Найчастіше таке рішення потрібно у випадках, коли ви хочете мати один об’єкт, що відповідає за один реальний об’єкт з життя (наприклад, користувачі, замовлення, документи і так далі). У той же час такий підхід буде зайвим для об’єктів дат, грошей, діапазонів і тому подібне.