Що таке рефакторінг?

Рефакторінг – зміни, що зроблені у внутрішній структурі ПЗ, щоби зробити його легшим для розуміння і швидшим для модифікації без зміни зовнішньої поведінки. Також, це перебудова ПЗ через застосування послідовності рефакторінгів без зміни зовнішньої поведінки ПЗ.


Рефакторінг покращує дизайн ПЗ. З часом, в код вноситься багато додаткових змін і ПЗ з часом втрачає свою структуру. Втрата структури має кумулятивний ефект. Чим важче побачити дизайн в коді, ти важче зберегти його і тим швидше він розпадається. Також, такі зміни спричиняють надлишковість та дублювання коду, тому систему важче зрозуміти та модифікувати.


Рефакторінг робить ПЗ більш зрозумілішим.


Коли потрібно робити рефакторінг:

Smells Catalog and possible re-factorings


Погані запахи в коді:

Moving Features Between Objects (basic)


  Move Method (Виділення методу) – виокремлюємо окремий метод, якщо метод є занадто довгим, або містить код, який вимагає коментарів.


  Move Field (Переміщення поля) – здійснюється тоді, коли поле використовується іншим класом частіше, ні в тому, де воно визначене.


Organizing Data (basic)


  Encapsulate Field (Інкапсуляція поля) – одним із головних принципів ООП є інкапсуляція, або приховування даних. Якщо зробити дані відкритми, обєкти зможуть читати та змінювати їх значення без відома власника цих даних. Тому робимо таке поле закритим та забезпечуємо методи доступу.


  Encapsulate Collection (Інкапсуляція колекції) – часто в класі міститься колекція єкземплярів. Ця колекція може бути масивом, списком, множиною чи вектором. Метод отримання не повинен вертати сам обєкт колекції, тому що це дозволило б клієнтам змінювати вміст колекції без відома класу, який нею володіє. Тому значення, яке вертає метод, потрібно зробити доступним тільки для читання та створити методи додавання/видалення елементів.


Composing Methods (basic)


  Extract Method (Виділення методу) – якщо є фрагмент кода, який можна згрупувати, винесіть цей фрагмент в окремий метод з назвою, яка пояснює його призначення. Таким чином, назва методу буде замінювати коментарі.


  Inline Method (Вбудова методу) – інколи корисно перемістити тіло методу в код, який його викликає. Буває, що тіла методів такі ж зрозумілі, як і назва самого методу. Також може бути ситуація коли є багато різних методів, структура яких є невдалою і тому краще іх всіх скинути в один загальний метод, а потім виділити методи іншим способом.


  Inline Temp (Вбудова тимчасової змінної) – заміна тимчасової змінної, якій присвоюється простий вираз лише один раз. Інколи така змінна заважає проведенню інших рефакторінгів.


  Replace Temp with Query (Заміна тимчасової змінної викликом методу) – використовується коли тимчасова змінна використовується для збереження значення якогось виразу. В таком разі, вираз замінюємо на метод і всі посилання в коді на цю змінну замінюємо новим методом.


  Split Temporary Variable (Розщеплення тимчасової змінної) – застосовується, якщо одна тимчасова змінна використовюється для багаторазового присвоєння різних результатів (якщо лише це не змінна, яка використовується в циклі в циклі і не змінна для накопичення результату). В такому разі створюємо окрему змінну для кожного присвоєння.


Simplifying Conditional Expressions (basic)


  Decompose Conditional (Декомпозиція умовного оператора) – виконується, коли ми маємо умовний ланцюжок перевірок (if-then-else). Замінюємо окремими методами умову (if), частини then та else. Сприяє покращенню розуміння причини розгалуження, а імена методів пояснюють призначеня відповідного фрагменту коду.


  Consolidate Conditional Expression (Консолідація умовного виразу) – здійснюється, якщо є ряд перевірок умов, що дають одинаковий результат. Потрібно обєднати всі перевірки в один умовний вираз або метод.


  Consolidate Duplicate Conditional Fragments (Консолідація дубльованих умовних фрагментів) – один і той же фрагмент присутній у всіх розгалуженнях умовного виразу. Потрібно перемістити даний фрагмент коду за межі цього виразу.


  Remove Control Flag (Видалення управляючого прапора) – існує змінна, яка діє як управляючий прапорець для ряду логічних виразів. Використовуємо замість нього BREAK або RETURN.

  Replace Conditional with Polymorphism (Заміна умовного оператора поліморфізмом) – здійснюється, коли існує умовний оператор, поведінка якого залежить від типа обєкта. Потрібно, перемістити кожні гілку умовного оператора в перегружений метод підкласу. Зробіть вихідний код абстрактним.