Ефект другої системи
Коли технічний борг команди потихеньку починає перевищувати всі мислимі і немислимі межі, то у команди з'являється як мінімум два способи його погашення: відрефакторити систему таким чином, щоб вартість майбутніх змін була не настільки високою або залишити поточну версію системи в спокої і переписати все заново. У першому випадку легко зіткнутися з синдромом рефакторингу, коли зміни робляться не з розрахунком зменшення вартості майбутніх змін, а вносяться просто заради змін. У другому ж випадку може виникнути «ефект другої системи», коли розвиваються і вдосконалюються вже нікому не потрібні функції системи, а думка «а чи не переписати все нафіг» є першою і єдиною, яка приходить в голову команді, як тільки вона стикається з чужим кодом.
І хоча в класичному розумінні «ефект другої системи» трохи відрізняється від паталогічної нелюбові до чужого коду і постійного його переписування, обидва ці випадки мають і щось спільне, так що має сенс обидва ці симптоми розглянути спільно.
Класичний ефект другої системи
Якщо подивитися уважно по сторонах, то можна помітити чудовий прояв ефекту другої системи при... виховання дітей. Бабусі та дідусі часто ставляться до виховання онуків зовсім не так, як вони ставилися до виховання власних дітей. Та й самі батьки дуже часто намагаються виправити свої власні проблеми, прищеплюючи дітям любов до того, що цікаво їм, намагаючись, щоб діти досягли їх недосяжних цілей.
Оскільки багато розробників і архітекторів теж вкладають свою душу при створенні програмних систем, зовсім не дивно, що приступаючи до нової версії свого дітища, вони намагаються виправити всі помилки і недоліки, і намагаються створити ідеальну систему. Крім того, окрилені успіхом першої системи (у разі невдачі все просто, до другої версії системи справа просто не доходить) розробники починають думати, що у них достатньо знань і досвіду в даній предметній області, щоб на основі існуючий приватних знань робити загальні висновки. Це часто призводить до передчасного узагальнення (premature generalization) рішення, що дуже часто вважається злом не меншим, ніж передчасна оптимізація (*).
Іншою проблемою при створенні другої системи є неправильна переоцінка цінностей, коли доводяться до досконалості морально застарілі функції системи, а принципово нові підходи і рішення не розвиваються. Це призводить до приголомшливої реалізації нікому не потрібних функцій, що може і корисно з суто естетичної точки зору, але навряд чи корисно для успіху системи.
Всі ці проблеми описані ще Фредеріком Бруксом в його «Міфічному людино-місяці», де крім опису цієї проблеми даються і рекомендації щодо її вирішення. І хоча вона вийшла задовго до іншої чудової книги Енді Ханта і Дейва Томаса «Програміст-прагматик», Брукс дає ту ж саму пораду, що і постійно звучить у книзі прагматиків: не потрібно крайнощів, і побільше прагматизму і самодисципліни.
Синдром «А чи не переписати все нафіг»
Погодьтеся, що ми-то з вами знаємо, чому розробка попередньої системи, яку робила сусідня команда, провалилася. От якби я керував би її розробкою (був би її архітектором/лідом/девелопером підкреслити потрібний варіант), я б все зробив по-іншому, і ми б точно не зірвали терміни на півроку, та й глюків було б в 4 рази менше.
Однак проблема полягає в тому, що більшість людей з деякою зарозумілістю дивиться на невдачі інших людей, короткозоро вважаючи, що вони б впоралися краще. 87,5 відсотків програмістів вважають, що вони б цю роботу зробили краще, і лише 2,5 відсотка (* *) з них зробили б її краще насправді. Решта ж просто зробили б її «по своєму», правда з тим же успіхом в плані термінів, якості та функціональності.
Крім програмістів подібною фігнею страждають ще керівники і замовники. Скільки разів ви стикалися з ситуацією, коли вам «пропонували» переписати систему, просто тому що в поточній версії вже ніхто не розбирається? Причому вимоги пропонувалося вивужувати самостійно з коду цієї ж системи, за яким пройшлося стадо індусів. Так що зрозуміти, що за хрінь там відбувається вже досить складно, і що повинно бути в результаті також зрозуміло, як теорія відносності десятирічній дитині.
В результаті якість нової системи визначається найслабшою ланкою всього ланцюжка розробки, а за відсутності вимог, високою вона вже ніяк бути не може. Ось і виходять ті ж яйця, але вид збоку, правда на деякий час нова система стає більш «розширюваною», оскільки вона поки що зрозуміла тій парі бійців, які розсекретивали існуючу логіку в процесі її перенесення в нову систему.
Якщо синдромом другої системи при бажанні можна побороти або, принаймні, істотно знизити ризик клінічних випадків, то з проблемою переписування впоратися дещо складніше. Якщо схильність до переписування таїться в душі програміста або архітектора, то боротися з нею потрібно аналогічним чином. Дійсно існують випадки, коли не просто можна, але саме потрібно спалити мости і почати все з чистого аркуша, але в більшості випадків до таких спроб потрібно точно так само ставитися з прагматизмом і обережністю.
Якщо ж це є вимогою менеджера або навіть замовника, то в цьому випадку, швидше за все альтернатив просто не залишиться: доведеться переписувати; при цьому просто варто постаратися не проміняти шило на мило і постаратися максимально врахувати основні помилки попередньої системи.
--------------------------------------
(*) В деякому роді передчасне узагальнення можна розглядати, як передчасну оптимізацію архітектурних рішень. Різниця полягає лише в тому, що коли мова заходить про передчасну оптимізацію, то це стосується непотрібного марнотратства трудових ресурсів, спрямованих на непотрібне підвищення продуктивності додатку. А коли мова заходить про передчасне узагальнення, то це стосується аналогічної за змістом витрати часу і сил, але на непотрібне узагальнення рішення.
(* *) Науково доведено, що 78,5% статистичних даних беруться зі стелі:)