Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 Контент вільний від AI. Цей пост на 100% написаний людиною, як і все на моєму блозі. Насолоджуйтесь!

16.05.2024

Коли DRY не працює


Два дні тому вийшла Dread Delusion - затишна та особлива гра про мандрування чудернацькими островами. Нагадує King’s Field, але з відкритим світом.

Поділюся сьогоденним рефакторингом, яким дуже задоволений.

Історія така. Є розділ застосунку (насправді ActiveAdmin), де в багатьох місцях будуються адреси деякого ресурсу. Це в Rails робиться легко, так й код чистий.

Нововведення таке, що цей ресурс може існувати як самостійно, так і вкладений в інший ресурс. На кшталт такого: були просто “заклади”, а тепер зʼявилися у них власники; заклади власника можна переглядати окремим списком — проте загальний список теж залишився.

Задача: коли переходиш з власника на його заклади, а потім, наприклад редагуєш та зберігаєш — то маєш опинитись знову на списку закладів власника. (А якщо з загального списку — то повернутись туди.)

Ніби все просто та є навіть вбудована можливість зробити вкладеність ресурсів на рівні маршрутів. Але… тепер кожне місце, де будується адреса, повинно зʼясувати в якому ми режимі та побудувати або /owners/1/places/2, або /place/2.

Перша спроба розсипала по коду відповідні розвилки if - що негайно засмутило Rubocop, та й вочевидь мало поганий вигляд. Замінити розвилки єдиною функцією (тобто класично “підсушити” код) немає можливості, бо вони відрізняються начинкою — маршрути всюди різні.

Тоді придумав взяти ті if та витягнути всі в окремий модуль. Ну й нехай в ньому три майже однакових методи — зате тепер вони семантично сполучені. Читачам буде легко зрозуміти їхню мету, а може навіть пізніше порефакторити краще.

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