Що нам робити з Enterprise-розробкою

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

І почати треба, природно, з огляду деталей того, що зараз пропонує ринок і академічне середовище.

Складність

Найперша проблема, я б сказав — мати всіх проблем — це складність. Складність всього — від предметної області до архітектури самих Enterprise-додатків. І ці складності нашаровуються і викликають один одного. І множать один одного. Тому давайте з них і почнемо.

Відразу скажу, я не претендую на якісь академічні пізнання. Я — звичайний керівник невеликий софтверної компанії. Однак я в цьому бізнесі давно (вже більше 20 років) і інформацію шукати начебто вмію. Більше того — я взагалі цікавлюся Computer Science. У будь-якому разі так я бачу ситуацію. Якщо я помиляюся, можете мене поправити — я відкритий до нової інформації.

Отже, результат мого дослідження такий: в академічних колах навколо проблеми складності суцільне бла-бла-бла. Тобто буквально: «Ось у нас гістограма складності завдань, а ось у нас графік зростання складності, давайте тепер накладемо їх один на одного і будемо медитувати на результат». Я цілком допускаю, що результатом цих «накладень» і «медитацій» рано чи пізно стануть якісь практичні рекомендації, але поки одне суцільне балабольство.

У бізнесі все ще гірше. Зі складністю тут ніхто не бореться. Нею навіть пишаються — тут у нас все так складно! Більш того, якщо ви прийдете до вашого керівництва і почнете пояснювати, що складність — це погано, з нею треба боротися, спрощуючи і стандартизируя все і вся, вам швидше за все скажуть: «Ти що, НЕ ТЯГНЕШ?!». Так, у нас складно. Але ми СПРАВЛЯЄМОСЯ.

Проблема ускладнюється тим, що Enterprise-додатки ростуть як трава при дорозі — без єдиного плану і взагалі без будь-якого бачення загальної картини. Нам потрібен ось такий функціонал — ми його запилили прямо тут і зараз, не думаючи про те, що цей функціонал знадобиться ще в кількох інших місцях і там його доведеться робити заново, або банально копіпаст. Винесення чого-небудь в загальні частини (shared services) в більшості випадків утруднене, оскільки виходить за межі компетенції керівників відділів замовника — така частина вже незрозуміло ким повинна супроводжуватись. У сенсі — була частина системи, що відноситься до компетенції одного відділу та частина, що відноситься до іншого відділу. А до чиєї компетенції повинна ставитися загальна частина? Вже незрозуміло.

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

Отже, що ж я пропоную робити з цією проблемою:

  1. Взяти мету на спрощення предметних областей, стандартизуя терміни та їх визначення, відкидаючи дублюючі поняття і визначаючи всі терміни максимально жорстко, без можливості багатозначного трактування. Я розумію, що компанії звикли працювати в понятійному хаосі (не вірите — почитайте документацію IBM, там пекло видно прямо відразу), однак необхідність таких змін навіть не назріла, а перезріла.
  2. Виділення відповідальних. Я, як людина, яка більше 20 років зайнятий у розробці і понад 15 років керує програмістами, можу сказати точно одне: якщо для якогось діла не призначені відповідальні, то це справа з місця не зрушиться НІКОЛИ. І питання не в тому, що люди погані. Питання в тому, що у всіх є своя робота, за яку з них і питають. А за роботу зі спрощення предметної області, стандартизації, обміну інформацією і т. д. — ні з кого не питають. Значить ніхто нею не займається, тому що завжди є більш важлива робота. Так ось. Треба нарешті визнати проблему і виділяти окремих фахівців (групи фахівців), які відповідають саме за систему в цілому. Тільки в цьому разі ми можемо розраховувати на позитивні зміни.
  3. Підтримка актуальності та повноти архітектурних документів. Якщо є на світі щось, що програмісти люблять менше, ніж писати юніт-тести, — так це написання документації. Як часто жартують в Enterprise — програма відмінно документована на мові Java. Так ось, ця ситуація неприпустима. Документування системи повинно стати найважливішою частиною її розробки. Архітектурні документи, особливо UML-діаграми (з будь-яким ступенем деталізації — від саб-систем до рівня коду) повинні бути легко доступні будь-якому розробнику і бути єдиним джерелом інформації по архітектурі додатки. Природно, такий підхід вимагає розробки маси додаткових правил і методик. І це справа не однієї статті. Однак починати цим треба займатися саме зараз, а краще — вчора. А не тоді, коли системи перестануть справлятися з навантаженням.
  4. Стандартизація — одне з найпростіших і відмінно себе зарекомендували засобів для боротьби зі складністю і гетерогенністю. Кожен, я думаю, прекрасно пам'ятає, як 10 років тому, входячи в офіс, кричали: «А у кого зарядка від маленької нокії? Ні, плоска не підходить». Нічого, як-то стандартизовались — живемо. Всім начебто зручніше стало. Мене, чесно кажучи, дещо бентежить те, що в нашій сфері процес йде у зворотний бік. Ось, наприклад, історія інтеграції. Замість стандартної до скреготу зубовного CORBA, прийшли більш м'які, але все ж стандарти SOAP, а на зміну їм — REST, про що єдине, що можна сказати: «Це не протокол і не стандарт, а архітектурний стиль». Стиль такий. В сенсі «я художник, я так бачу». І якщо інтеграція REST з JS мордою або мобільним додатком виглядає ок (переваги JSON для цієї інтеграції очевидні), то почастішали останнім часом випадки інтеграції В2В додатків з допомогою REST виглядають абсолютно не кращим варіантом. Ну в будь-якому випадку стандартизація — наше все.
  5. Обмін інформацією — наріжний камінь вирішення найбільш важких і неприємних проблем в розробці. Як показує моя практика, розробники вкрай рідко спілкуються на виробничі теми з колегами не з суміжних проектів. Так і з колегами із суміжних — тільки за потребою. Що я пропоную зробити для виправлення ситуації:
    • Крос-командні мітинги. Робота над будь-яким проектом практично не буває повністю рівною — частіше трапляється то густо, то пусто. Так ось, було б добре витрачати час, коли «порожній» на те, щоб підготувати коротку презентацію архітектури та основних технічних рішень для суміжників. І звернутися до них: «Хочете, ми вам розповімо про свій проект? Коротенько — на годину-півтора, більше не треба». А потім попросити, щоб вам презентували свій проект. Слухачі будуть зацікавлені — зрештою, всім цікаво, над чим працюють колеги з сусідньої кімнати, тим більше якщо у вас ще є і інтеграція. Можна набратися якихось знань з типовим рішенням, та плюс ще — блиснути своїми знаннями. Якщо проводити такі зустрічі досить часто, то обмін інформацією усередині компанії покращиться в рази.
    • Загальні вікі. У будь-якій компанії з часом накопичуються тонни інформації по взаємодії з легасі софтом замовника, по правильному використанню сформованої інфраструктури з урахуванням обмежень сек'юріті. Неприємно, що більшість цих дрібних рішень так і залишаються в голові того, хто їх знайшов. Ну максимум — у своїй команді. Природно, такі знання треба акумулювати і робити загальнодоступними (у рамках компанії, звичайно). Як на мене, найзручніше на цей момент рішення — це движок вікі. Наскільки мені відомо, у багатьох компаніях такі вікі стоять, проте використовуються вони вкрай рідко, та інформація там буває вже давно не актуальною. Як правило, рішення такої задачі впирається у відсутність відповідальних. Я б запропонував підпорядкувати вікі фахівця (або групі), що відповідає за загальну архітектуру (я розповідав про це в пункті 1).
    • Навчання корпоративним стандартам. Ніяка стандартизація неможлива, якщо безпосередні виконавці не знають про існування стандарту. Взагалі, я, як фахівець з навчання, із сумом змушений констатувати практично повну відсутність роботи в разработческих компаніях над освітою співробітників. Навчання, яке проводиться, часто робиться для галочки, засобами власних співробітників і результат назвати, окрім як «з вторпродукта і палиць», складно. А якщо говорити про власне навчанні корпоративним стандартам... Ой, а вони взагалі в кожній компанії існують?

Монолітність

Монолітність в останні роки — улюблений об'єкт для боротьби (про пристрасть шукати не там, де втратили, а там, де світло, я вже писав). Ну так ось. Тут місце, де світло, точніше золотий молоток (вдаючись до іншої аналогії) знайшовся. Це були... ви вже здогадалися? Так-так. Микросервисы, звичайно.

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

Однак і тут є кілька проблем, які старанно ігноруються. Я б звернув увагу на такі з них:

  1. Виникає додаткова гетерогенність. В більшості своїй на SOA/микросервисы переводять не всі Enterprise-програма, а лише невелику його частину, а найчастіше — тільки один модуль. В результаті монолітність усього додатки нікуди не дівається (від моноліту відкусили тільки маленький шматочок), а ось гетерогенність всієї системи збільшилася. Не можна сказати, що це так вже добре. Ну і ми можемо прогнозувати, що з появою нових підходів частини проекту, зроблені на SOA/микросервисах так і залишаться жити пам'ятниками свого часу, як і купи нашарувань, зроблених на золотих молотках свого часу.
  2. Від введення додаткової архітектури в проект, складність всього проекту явно не зменшиться. Більш того, сама програма на микросервисах часто виявляється складніше для розуміння, ніж монолітне.
  3. Остання проблема микросервисов і при цьому найважливіша, на мій погляд, — така архітектура не вирішує проблему монолітності сама по собі. Якщо архітектура микросервисного додатки не продумана, то насправді всі проблеми просто піднімаються на мережевий рівень і ховаються від погляду розробників. Тобто якщо раніше розробники змушені були думати над архітектурою хоча б свого модуля, то тепер, коли модуль розпався на купу микросервисов, над їх загальною архітектурою можна не замислюватися, оскільки незрозуміло, хто за все це загалом відповідає. Так, в теорії повинен відповідати тимлид або архітектор, однак я бачив повно команд, де архітектора не було, а тимлид цим не хвилювався. Ну і все, вже модуль починає рости як трава під парканом, приймаючи всі проблеми, перераховані в першій статті.

Є ще кілька менш очевидних і менш важливих проблем. Для прикладу наведу одну. Якщо ви розробляєте монолітне додаток, то фактично вже склався консенсус про спільне володіння кодом, і рано чи пізно інший програміст влізе в шматок коду, який ви написали, і запитає: «А це що за фігня?». З микросервисной архітектурою більшість команд провалюється в кошмар персонального володіння микросервисами: коли у кожного сервісу є власник, і тільки він його змінює. В принципі, зрозуміло, до чого це призводить.

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

Мої пропозиції по боротьбі з монолітністю:

  1. Офіційне поділ частин бізнесу. Складно домогтися модульності Enterprise-додатки, якщо воно є повним відображенням заплутаного, як клубок ниток, бізнесу. В ідеалі необхідно домогтися, щоб інтеграція між частинами Enterprise-програми, що відносяться до відання різних департаментів, відбувалася точно так само, з такою ж глибиною документування та стандартизацією, як інтеграція з зовнішніми системами.
  2. Стандартизація способів інтеграції. Ви вже, напевно, помітили, що я пропоную все стандартизувати. І це дійсно так. Якщо нам необхідно боротися з монстром у вигляді заплутаного клубка взаємодій різнорідних частин, то давайте хоча б доб'ємося, щоб частині були відносно стандартні і взаємодія їх було однотипним. Я маю на увазі, якщо у вас всі частини інтегруються за SOAP, наприклад, то давайте і нову інтеграцію зробимо на ньому. Навіть якщо SOAP тут явно надмірний.
  3. Єдиний реєстр микросервисов. Цю ідею мені розповів один слухач під час виступу. Він сказав, що в їхній компанії вважається, що микросервис готовий тільки тоді, коли автор завів його в загальний реєстр микросервисов компанії. З повним описом — що за сервіс, які у нього інтерфейси, що він повертає і що робить. Ідея здається мені просто геніальною. З одного боку, сервіс описує сам автор, що запобігає невірну трактування (автор-то точно знає, що він написав... я сподіваюся на це). Плюс до цього ми досить добре знижуємо ризик того, що готова функціональність буде розроблятися ще раз. Підвищуємо реюз готових сервісів і ще багато всякого хорошого. І все це ціною невеликого ниття програмістів, що «хочеться всю цю дурницю писати». Рекомендую робити також. Мене ще запитували: може, краще зробити систему автоматичного дискавера сервісів? Я вважаю, що ні, не краще. Як мінімум ви витратите тонну часу на цю систему. Але програмісти все одно напишуть такий сервіс, який буде дискавериться невірно. Плюс до цього ви не отримаєте коментарів від автора сервісу, а вони часто — найважливіше.
  4. Навіть якщо ви не хочете вести загальний реєстр микросервисов, в будь-якому випадку необхідно на рівні організації затвердити список необхідної інформації, яка повинна бути в документації по кожному микросервису.

Гетерогенність

Як я вже писав у першій частині статті, гетерогенність у більшості випадків ігнорується і часто навіть вітається як фіча, а не баг, а то й ставиться в заслугу. У нас тут стільки всяких технологій на проекті!

А взагалі ми знаємо, як програмісти борються з проблемою гетерогенності: у нас є новий золотий молоток (new shining thing, за влучним висловом Роберта Мартіна), так давайте все зробимо цим новим золотим молотком. А оскільки зараз у нас улюблений золотий молоток — микросервисы, так давайте все зробимо на микросервисах. Але про проблеми цього рішення я писав у попередній главі, повторюватися не буду.

Якщо проаналізувати вимоги до Enterprise Java розробникам по вакансіях, то ми побачимо, що ринок вже своє слово сказав: ставка на сьогоднішній момент зроблена на стек фреймворків Spring. Я вітаю будь-яку стандартизацію. Але от як раз до стеку спринга у мене є кілька претензій:

Мої пропозиції по боротьбі з гетерогенністю:

Інтеграція

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

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

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

Фокусування на цю проблему уваги всього персоналу, в першу чергу — технічного. Так як саме він часто приймає рішення з цих питань.

Обсяги даних

Не можна сказати, що індустрія ігнорує запит на обробку великих даних. Скоріше навпаки: будь-який технічний виклик є для індустрії своєрідним приводом для появи нових підходів і засобів. А вже обробляти величезні масиви даних — це сама по собі дуже цікава технічна задача. Як ви знаєте, всі ці підходи виділилися в окремий напрям Big Data, яке, природно, відразу ж стало новим золотим молотком. Ну хто б здивувався.

Раз є рішення для цієї проблеми, бізнес тут же став знаходити все більше і більше способів отримувати все більше і більше даних. Але про це я говорив в минулій статті.

Як у будь-якого інструменту, рішень Big Data є і свої проблеми:

Зрозумійте мене правильно, я не проти ніяких рішень. Тим більше таких нових, красивих, блискучих, та ще й розширюють наші можливості обробки даних, як Big Data. Я проти бездумного використання чого б то не було. І я проти того, щоб у будь-якому інструменті бачити Silver Bullet.

До речі, про срібної кулі, на роль якої в очах багатьох новачків у програмуванні претендують NoSQL бази даних. Але, як звичайно, і тут не обійшлося без проблем. Коротко нагадаю:

Мої пропозиції щодо використання технологій Big Data:

Загальні рекомендації

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

Отже, це своєрідний маніфест здорового глузду.

Комунікації — важливіше технологій

Весь мій досвід привчив мене, що якщо в розробці проблема, то вкрай рідко це технологічна проблема. Так, так, звичайно, буває, і це благословенний момент, коли програміст може розвернутися у всю міць своїх сил. Однак у більшості випадків проблема лежить в площині передачі і обробки інформації. І як ми знаємо за правилом Парето — 20 % зусиль дають 80 % результату. Зосередитися треба саме на цих проблемах, щоб отримати більш суттєве покращення в цілому. Якщо ми подивимося на список основних причин провалів IT-проектів, то практично всі вони тим чи іншим способом відносяться до комунікації між людьми. Ось це і треба виправляти.

Архітектурні рішення — важливіше використовуваних засобів

Чесно кажучи, прийняття рішення про використовуваному стеку технологій ДО того, як прийняті хоч якісь архітектурні рішення, бич сучасного Software Engineering. Найнеприємніше, що, якщо ми візьмемо список тем будь розробницьких конференції, ми побачимо теми «про нові можливості фреймворка Х», «використання нової мови Y ... системах» та «нове API бібліотеки Z». Але ніколи не побачимо «складні випадки декомпозиції предметної області» або «визначення відповідної технології під готові архітектурні рішення». І треба сказати, що ця ситуація виникла не на рівному місці. Якщо ми згадаємо, наприклад, надпопулярний зараз стек технологій Spring, то побачимо, що саме стек технологій диктує нам архітектуру, а не навпаки: ми зможемо використовувати його на вже побудованій архітектурі. І це, по-моєму, дорога у безвихідь.

Стандартизація — важливіше ідеального відповідності інструменту задачі

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

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

Удачі!

Опубліковано: 14/08/17 @ 10:00
Розділ Різне

Рекомендуємо:

.NET Core in da Cloud
Особливості віртуалізації Xen в автомобільній сфері
DOU Books: 5 книг, які радить Всеволод Демкин
DOU Ревізор в Depositphotos: «Фабрика фотографії з величезними open space»
Огляд ІТ-ринку праці: Хмельницький