Энтерпрайзные проекты убили профессию разработчика +14



От переводчика: Фокусом нашей компании всегда была именно разработка корпоративных приложений. В Haulmont мы занимаемся как созданием собственно приложений, так и инструментов, позволяющих разработчикам эффективнее решать задачи, связанные с разработкой таких систем. Например, наш фреймворк Jmix предназначен для корпоративной разработки, мы это заявляем в рекламе и анонсах. И конечно же, пройти мимо статьи с таким названием мы просто не могли. В Jmix есть все, чтобы сделать разработку корпоративных приложений интересной и успешной, кроме одного: он не может повлиять на людей, которые принимают решения о методах и процессах разработки. Почитайте статью, возможно, она заставит вас задуматься, о том, как можно поменять вашу корпоративную разработку, чтобы все участники были довольны.


На эту статью меня вдохновил комментарий на HackerNews, который я больше не могу найти. Суть его была такая: “В то время, как архитектура слишком проработана, код недоработан”. Если кто-то опознает автора, я с радостью проставлю его авторство.


Заранее в свою защиту хочу сказать, что этот текст описывает только мой опыт за последние 10 лет работы консультантом. Возможно, есть методики и фреймворки, которые решают проблемы, описанные ниже, но они либо не применялись, либо применялись неправильно.


Что такое корпоративная разработка?


Термин не стандартизован и часто используется по-разному в разном контексте. На мое понимание того, что такое корпоративное программное обеспечение, сильно повлияло определение Мартина Фаулера из книги “Шаблоны корпоративных приложений” (2002, Addison Wesley).


  • Разработано для внутреннего использования в организации


  • Работает со сложными данными, которые хранятся в разных источниках


  • Работает со сложными бизнес-правилами


  • Обычно — многопользовательское (что означает одновременное использование)


  • Обычно интегрировано в общую корпоративную IT среду



Разработчики в разговорах зачастую преуменьшают значимость работы над корпоративными приложениями. Конечно, эти проекты не приводят к появлению новейших технологий, в них не будет разработан новый кодек потокового вещания и в них не используется блокчейн (а он вообще ещё используется?).


Но, в то время как на поверхности разработка корпоративного ПО выглядит тривиально, по сути, оно включает в себя решение весьма сложных проблем относительно работы с данными. Разработчики вынуждены работать с большим количеством данных из разных источников.


Каждый источник может определять одну и ту же сущность в своем домене, которая совсем чуть-чуть отличается от определения в другом домене. И это делает трансформацию данных между доменами весьма сложной задачей.


Вдобавок к этому, разработчикам необходимо принимать во внимание тонны сложных бизнес-правил, количество которых в системе постоянно растет.


Проблемы с разработкой программного обеспечения


Я принимал участие во многих проектах разработки корпоративного ПО в качестве внешнего разработчика и консультанта и часто видел, как проектные подходы мешали достижению цели создания ПО. По моему мнению, проектный подход — неподходящая среда для создания отличного программного обеспечения. Основные атрибуты проекта:


  • Ограничения по срокам и бюджетам


  • Команда формируется только на ограниченное время



Задача менеджера проекта — убедиться, что проект достиг целей за заданное время и бюджет. Если это как-то достигнуто, то проект считается успешным. Бюджет зачастую фиксирован, равно как и набор целей, которых нужно достичь.


Первый фундаментальный недостаток для меня — это фиксированный срок окончания, что подразумевает, что ПО “готово” в какой-то момент времени. Обычно это “решается” разделением разработки на “фазу проекта” и “фазу поддержки”. Когда проект "завершен", команда разработчиков обычно распускается и ПО передается “команде поддержки” (обычно с большой долей джунов).


Выгода такого подхода в том, что проектная команда должна тщательно задокументировать продукт, перед тем как передать его (В теории. Иногда эта часть проекта пропускается, потому что заканчивается бюджет). И это приводит ко второй проблеме в проектном подходе: в процессе передачи программного обеспечения другой команде теряется большое количество знаний.


Чтобы избавиться от недостатков проектного подхода, многие компании пытаются внедрить гибкие фреймворки, в основном SCRUM. Лично я никогда не видел SCRUM или другую гибкую методологию, которая бы работала при проектном подходе. Хотя я субъективен, потому что компания, которая по-настоящему живет ценностями гибких методологий разработки, никогда не будет делать программное обеспечение в рамках проектного подхода, и уж точно не с внешним консультантом. В таких компаниях понимают, что их ПО — это продукт, который нужно постоянно развивать.


Стандартизация


Принимая во внимание проблемы, описанные выше, одной из главных забот во всем цикле разработки корпоративного ПО становится избегание “сюрпризов” в коде. Если код был передан новой команде проекта или команде поддержки, он должен быть понятным, чтобы новая функциональность или исправление были внесены с наименьшим количеством усилий. Основной инструмент для этого — стандартизация.


В больших корпорациях для этого зачастую существует команда “Корпоративной Архитектуры”, которая сидит выше всех проектных команд и стандартизирует процессы разработки. Какой язык использовать? Какие фреймворки и библиотеки разрешены? Какой технологический стек требуется, какой подход для тестирования? Какие архитектурные правила необходимо соблюдать? Эта макро-архитектура зачастую описана с потрясающим уровнем детализации.


И, до определенной степени, это имеет смысл: если разработчики используют проектный подход, им приходится работать с разными кодовыми базами с течением времени. Команда поддержки может отвечать за несколько разных приложений одновременно. Если разработчики “чувствуют себя как дома” во всех этих приложениях, т.е. они моментально распознают структуру и технологии, то они могут начинать работать над ними значительно быстрее.


Самое сложное — избегать создания слишком большого количества правил. Я работал на клиентов, которые специфицировали конкретную версию Spring Boot, которую надо использовать. Если архитекторы меняли версию, то вся компания принудительно переходила на новую.


Я работал на клиентов, которые предписывали использовать Hibernate только с HQL, обычный SQL был под запретом, равно как и другие фреймворки, использование проекций и POJO.


“За” такой подход было то, что разработчикам не нужно было осваивать SQL, а способ доступа к БД был стандартизирован. Но, конечно же, это приводило к тому, что производительность была не на самом высоком уровне в большинстве приложений. Кроме того, фирменные особенности дорогущей СУБД Oracle Enterprise не могли быть использованы.


Но даже когда эта стандартизация приводила к огромным проблемам в проектах, с архитекторами нельзя было спорить. Нытьё разработчиков — это не повод ломать Архитектуру, не так ли?


Многоуровневая архитектура


“Золотой стандарт” стандартизации — многоуровневая архитектура. Следуя определению Фаулера из книги “Корпоративные шаблоны проектирования”: слои — это техника разбиения сложного программного обеспечения на составные части.


В теории, вынесение работы с данными, бизнес-логики и представления в разные слои упрощает работу с приложением. Каждый из них должен знать только о слоях ниже, т.е. бизнес-логика знает только про слой работы с данными, но не знает, что ее вызывает: REST сервис, веб приложение, графический клиент или утилита командной строки.


Это не только структурирует приложение, делая его простым для понимания, но и затрудняет смешивание различной функциональности. Однако, это также разделяет бизнес-логику на разные поддомены, что может повлиять на производительность, т.к. для перемещения данных между доменами требуются их преобразования.


Почему это все приводит нас к недоработанному коду?


Чем больше зарегулирована среда для разработчика, тем более недоработанным становится код. Для меня, недоработанный код — код, который мог бы выполнить задачу быстрее, с меньшим количеством строк кода или меньшим дублированием.


Из примера выше: если разработчикам запрещено писать SQL, они будут ограничены только HQL. Это выльется в более медленные запросы или большее количество запросов в сравнении с SQL для выполнения одного и того же задания.


Если подробно расписано, какой язык, фреймворк или библиотеку использовать, то разработчики иногда вынуждены изворачиваться, чтобы решить поставленные задачи вместо того, чтобы использовать наиболее подходящий инструмент.


Если до фанатизма следовать многоуровневой архитектуре, то 50% вашего кода будет представлено мапперами данных для передачи между слоями. Если вы всегда будете помнить о том, что рано или поздно наступит "тот самый" ужасный момент передачи кода в другую команду по окончании проекта, то вы будете осторожнее и начнете избегать лучших решений в пользу более понятных.


Последствия для разработчиков


Разработчики, которые работают в такой зарегулированной атмосфере довольно долгое время и каждый день пишут недоработанный код, теряют мотивацию и перестают изучать что-то новое.


Я сам был в этой шкуре: когда получаешь задачу на реализацию новой функциональности, обычно склоняешься к написанию наиболее простого кода, отметая более эффективные пути решения, потому что опасаешься, что более сложный код не будет понят командой поддержки, которая вскоре заберет проект.


Все обсуждения пулл реквестов сводятся к выяснению, действительно ли нужна абстракция для этой функциональности, не был ли слишком экзотическим примененный шаблон или не был ли SQL слишком сложным. Не слишком ли твой код отходит от стандартов.


В конце-концов тебе становится все равно, есть ли лучший способ решения проблемы, ты автоматически выбираешь самый очевидный и простой способ. Ты перестаешь расти и становишься плохим разработчиком, который пишет код “по наименьшему общему кратному” для всех. Ты становишься ленивым.


В этих энтерпрайзных проектах “элегантный” и “умный” код — завуалированное оскорбление, которое я начал использовать, спустя некоторое время. Но ведь нет ничего плохого в написании такого кода. Если он решает проблему как нужно, это нормально, чтобы другие разработчики подумали про этот способ. И можно даже документировать этот код, чтобы немного упростить им задачу ????


Как улучшить ситуацию?


Относитесь к программе, над которой работаете, как к продукту, не как к проекту. Потом вы можете убрать некоторые детали из вашей макро-архитектуры. Если над проектом работает одна и та же команда долгое время, они могут “рискнуть” и специализироваться на своей технологии, выбирая наиболее подходящие под задачи инструменты и архитектурный стиль. Они могут добавить “риска” и написать более сложные алгоритмы, используя менее известные особенности языка. Знание останется в команде, останется и сама команда.


Хотя микросервисы сейчас далеко за пиком кривой хайпа, можно их использовать, чтобы достичь именно этого результата. Это не значит, что одна команда может запускать приложения на Go на Heroku, другая — PHP приложения на своем собственном сервере, а третья — Java приложения в kubernetes. Командам придется договориться о каких-то общих стандартах. Но их нужно не так много, как вам кажется.




К сожалению, не доступен сервер mySQL