Як уникнути гігантських методів клею?


21

На моїй теперішній роботі мені було доручено прибирати старий код кілька разів. Часто код - це лабіринт, а дані за ним ще більше заплутані. Мені здається, що я розбираю речі в приємні, акуратні, модульні методи. Кожен метод робить одне і робить це добре. Ось тоді все починає йти на південь ...

Незмінно я закінчую чистим API і немає реального способу пов'язати все це разом. Рішення полягало в тому, щоб написати великий потворний метод "клею" (як правило, повний умовних тверджень), який врешті-решт називає всі мої "чисті" методи.

Метод склеювання, як правило, стає тривалою версією клубка коду / даних, яку я намагався очистити. Це в цілому легше читати, але все одно дратує.

Як я можу уникнути таких методів? Це симптом заплутаних даних чи відображення чогось, що я роблю неправильно?


3
API призначені для використання. З заплутаного безладу, який ви отримали, ви створили API, а потім повторно заплутали його. Можливо, це просто бізнес-вимога. Але ви додали цінність, тому що хтось інший може прийти і легко зробити іншу функцію клею за допомогою вашого API. Не потрібно ламати руки ...
Депутат Aditya

1
Ми навіть тут говоримо про предмети або просто функціонуємо всюди?
Ерік Реппен

3
Я не думаю, що це дублікат цього питання, я кажу трохи більш загально (і в більшому масштабі, ніж одна функція).
cmhobbs

1
erik - Я говорю тут про об'єкти та методи. Я взяв пару умовних помилок і перетворив їх на API. Проблема виникає, коли прийшов час зателефонувати в API. Перша відповідь тут, можливо, саме те, що я шукаю, хоча.
cmhobbs

2
Як на землі це дублікат?
MattDavey

Відповіді:


12

Я дам вам наш досвід рефакторингу LedgerSMB. Ми прийняли рішення робити щось по-різному і все ще робимо саме те, що ви описуєте, але без великої кількості методів клею (у нас є кілька методів склеювання btw, просто не багато).

Життя з двома кодовами

LedgerSMB протримався з двома кодовими базами близько 5 років, і це буде ще декілька, перш ніж стара база коду буде усунена. Стара база коду - це справжній жах. Неправильний дизайн db, Perl створює, як IS->some_func(\%$some_object);поряд з кодом, який точно показує, чому метафора спагетті іноді використовується (шляхи виконання, що меандрують між модулями і назад, і між мовами, без рими чи причини). Нова база коду уникає цього, переміщуючи db-запити у збережені процедури, маючи більш чисту структуру для обробки запитів та багато іншого.

Перше, що ми вирішили зробити, - це спробувати переробляти модуль за модулем. Це означає переміщення всієї функціональності в певній області в новий модуль, а потім підключення старого коду до нового модуля. Якщо новий API чистий, це не велика справа. Якщо новий API не все стає волохатим, це запрошення попрацювати над новим API ....

Друга річ - багато випадків, коли новий код повинен мати доступ до логіки у старому коді. Цього слід уникати настільки, наскільки це можливо, оскільки це призводить до некрасивих методів склеювання, але не завжди можна цього уникнути. У цьому випадку клейові методи повинні бути зведені до мінімуму і уникати, наскільки це можливо, але застосовуватися при необхідності.

Щоб зробити цю роботу, вам потрібно взяти на себе зобов’язання переписати всю функціональність у певній області. Наприклад, якщо ви можете, наприклад, переписати одразу весь код відстеження інформації про клієнтів, це означає, що з кодом, який викликає це зі старого коду, не важко працювати, і відправка на старий код з нового коду зведена до мінімуму.

Друга річ полягає в тому, що якщо у вас є розумні абстракції на вашому місці, ви повинні мати можливість вибрати, на якому рівні API зателефонувати, і як зберегти це в чистоті. Однак вам слід подумати над тим, щоб переписати частини, які викликають ваш API, щоб вони також були чистішими.

Існує багато напрямків бізнес-інструментів, які є невідмінно складними. Ви не можете позбутися всієї складності. Але ви можете керувати ним, орієнтуючись на чисті API, які конкретно роблять те, що вам потрібно зробити, і модулі, які конструктивно використовують цей API. Клей повинен бути крайнім засобом лише після врахування, що перезапис решти викликового коду може пройти швидше.


Я думаю, що ти, можливо, вдарив цвях по голові. Причина існування клею може бути пов'язана з кодом, який викликає створений мною інтерфейс. Я збираюся почекати ще кілька відповідей, щоб побачити, якщо ми чогось не пропустили, але я вважаю, що це підсумовує це досить добре.
cmhobbs

1
"Шляхи виконання, що меандрують між модулями і назад, і між мовами, без рими чи причини", - це також нагадує про деякі сучасні практики OO.
користувач253751

8

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

Незмінно я закінчую чистим API і немає реального способу пов'язати все це разом. Рішення полягало в тому, щоб написати великий потворний метод "клею" (як правило, повний умовних тверджень), який врешті-решт називає всі мої "чисті" методи.

З процедурним кодом (навіть якщо він замаскований як OO), ви завжди будете в кінцевому підсумку з десь визначеним послідовним робочим процесом, часто заповненим складними умовними гілками, як ви описуєте. Я підозрюю, що саме ця процесуальна природа кодексу змушує відчути, що щось не так. Це не обов'язково погано, і при роботі зі застарілим кодом це може бути абсолютно неминуче


6

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


2
Ви тоді не отримаєте клеєве дерево?
Пітер Б

3
@ PieterB можливо, але простіше витягти різні залежності, коли у тебе різні завдання в різних методах. Після вилучення нових методів ви можете зробити ще один пропуск рефакторингу.
Paling

1

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

Це теж те, що ускладнює написання абстракцій. Навіть щось таке просте, як олівець - це розум згинання, якщо ви намагаєтесь утримати всі його шари абстракції в голові одразу. Головне - отримати один шар так, як вам подобається, що ви зробили, а потім забути всю складність, що лежить в основі цього шару, і зробити те ж саме на наступному рівні.


0

Це здається, що ви переробляєте API, просто думаючи про реалізацію API, але не замислюючись над кодом, який використовує API - тобто про "клей-код", про який ви говорите.

Якщо це правда, ви можете спробувати почати з іншого кінця. Перепишіть матеріали, які загрожують спочатку стати вашим некрасивим кодом клею, і створіть пару ще не реалізованих інтерфейсів, які стануть вашим API в цьому процесі. Не варто занадто багато думати про фактичну реалізацію цього API - це нормально, якщо у вас є відчуття кишки, що ви можете це зробити. І лише потім перепишіть лабіринт коду, щоб він відповідав цьому API. Звичайно, в цьому процесі відбудуться деякі зміни в API та коді клею, але він повинен краще поєднуватися.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.