Проблема
Скорость разработки и качество кода — вот, пожалуй, одно из главнейших противоречий IT-индустрии. Можно долго продумывать архитектуру приложения, потом ее совершенствовать, улучшать, а в итоге так ничего и не сделать. А можно быстро что-то сварганить, а потом и зарелизить, но из-за ошибок проектирования завести весь проект в тупик. На каждые два часа разработки, шесть часов будет уходить на поиск и исправление багов, в результате чего вся последующая разработка фактически застопорится.
Таким образом, вопрос: качество или скорость переходит в проблему: хороший, но вечно незаконченный проект или хоть как-то, но работающая программа. Любой менеджер как реалист, естественно, выберет второе.
Так и получается, что куда ни ткнись, у всех код если не дрянной, то по меньшей мере неважный. То, что называется многозначительным словом legacy. Все всё понимают, плюются, но поделать ничего не могут. Код уже есть и с ним нужно работать. Все предложения по улучшению не приветствуются, а то и прямо запрещаются. Ведь нужен функционал, а не код. Код существует для функционала, а не функционал для кода.
Корни проблемы
Механизм попадания в тупик простой. Проект начинается с одним видением. В процессе его реализации требования меняются или обнаруживаются неизвестные ранее особенности, и вот созданный код уже перестает соответствовать задаче. Тут бы его переписать, но все знают, что через неделю откроется еще что-то, и нужно будет всё переписывать снова. В результате проект так никогда и не увидит свет. Поэтому принимается волевое решение — продолжать. Продолжать во что бы то ни стало.
Объем функционала растет на отвратительной кодовой базе, в результате чего качество падает еще больше. Так как код не соответствует видению программистов, они перестают его понимать. Мозгов не хватает, чтобы держать в голове две "картины мира": то, что нужно сделать, и то, как это сделано в реальности. Код выходит из-под контроля разработчиков, и начинает жить своей собственной жизнью в плохом смысле этого выражения.
Процесс разработки становится непредсказуемым. Любое изменение в программе ведет к целому букету трудноуловимых багов. В нормальной системе, увидев баг еще в первый раз, можно предположить, где сломалось, и как это исправить. В плохой — сломаться может что угодно и где угодно, потому что программисты сами уже не вполне понимают, где что делается. Причину бага становится трудно определить даже через несколько часов поисков, особенно, если сам мистический баг не всегда воспроизводится. Так хаос порождает магию. А если точнее — бессилие перед хаосом рождает магическое мышление. Прямо как у первобытных людей.
Но одно дело найти ошибку, и другое — ее исправить так, чтобы не появились другие баги. На это можно потратить еще столько же часов. А то и дней. Так, почти все время из разработки плавно перетекает в исправление ошибок (багфиксинг), и всякое продвижение по графику останавливается.
В конце, превысив все возможные сроки, изможденные разработчики кое-как доводят проект до релиза с ограниченным функционалом. Потом начинают новый проект, и вся история повторяется. Каждый думает, что в следующий раз уже точно все будет по-другому. Но в реальности колесо сансары не так-то легко сломать. Как жители Урюпинска, которые плохо себя вели, после смерти снова попадают в Урюпинск, так и программисты, не переписывающие проекты прошлого, повторяют свои кармические ошибки снова и снова. И даже если местами и появляются тут хороший код, окружающий его плохой топит все в себе, как ложка меда тонет в бочке дегтя.
Решения
Конечно, следовало бы поступить по-иному. Если есть достаточный опыт и теоретическая подготовка, а проект перспективный, не одноразовый, то нужно сначала хорошенько разобраться в теме, выработать качественное решение, а потом уже на основе его серийно делать проекты. Делать проекты просто в надежде, что однажды они каким-то образом станут лучше, затея практически безнадежная. Сами по себе не станут. Когда разработчик начинает осознавать, что выбранный им путь ведет в тупик, то лучше уже тогда все бросить и, не оглядываясь на старый код, начать заново. И так несколько раз.
Например, клиентский фреймворк, который тут будет разбираться, переписывался раз 7 на протяжении (с большими перерывами) 12 лет, а серверный — раз 5 в течение 5 лет. Это значит, что компании нужно постоянно и целенаправленно работать над улучшением качества кода, и тогда лет через 5 она дойдет до приемлемого результата. Или нужно найти разработчиков, которые уже прошли этот путь и имеют соответствующий опыт за плечами.
Оба пути затратные, рискованные и явно не для всех. Не всяким программистам можно поручить такое задание, да не всякий и возьмется. Такой разработчик должен обладать целым комплексом качеств, которые все вместе встречаются довольно нечасто.
Во-первых, разработчик должен знать в совершенстве данный язык программирования и прочие инструменты, чтобы разные мелкие вопросы не отвлекали его от основной цели.
Во-вторых, требуется обладание техникой проектирования сложных систем и архитектур. А для этого нужно прочитать немало книг и успеть опробовать прочитанное на практике. Большую помощь в этом деле также может оказать изучение чужих исходников, а также других платформ и языков программирования, пусть они непосредственно и не нужны для работы.
Все это требует больших затрат времени, усидчивости и погруженности в предмет. Невозможно каждый день часами сидеть за компьютером и копаться в программе без того, чтобы тебе это не нравилось. Поэтому, в-третьих, должен быть сильный интерес и склонность к программированию, математике, технике, наукам вообще.
В-четвертых, и интерес, и склонности не берутся из ниоткуда. Все это можно только получить — от родителей, хороших учителей, товарищей, книг. Потом, нужны еще условия, в которых бы интерес не гасился, а, наоборот, поддерживался и укреплялся. И многих вы знаете среди своих знакомых, кто бы жил и работал действительно с интересом?
И это только для того, чтобы просто программировать. Но чтобы сделать что-то новое, нельзя ограничиваться только своей специальностью. Нужно еще иметь неплохие обзорные знания по другим смежным и несмежным наукам. Как минимум, хорошо бы понимать как устроено то, чем ты занимаешься — не только до железок, и даже не до атомного уровня, а вообще до начала времен, до Большого взрыва.
Можно, конечно, писать программы, не зная даже, как устроена операционная система, на которой они запускаются. При этом они будут хорошо работать, а тебе хорошо платить. Но в этом случае ты сам для себя будешь волшебником, творящим магию, смысл которой не понимаешь. А незнание порождает неуверенность и страх. Ну или, как минимум, отвлекает. В идеале, если бы тебя в машине времени перекинуло на 2000 лет назад, ты должен уметь так объяснить все устройство твоего мира и технологий, чтобы древние люди могли перейти в современность в течение жизни нескольких поколений.
Но не только уверенности и спокойствия ради нужно знать другие области знания. В каждой из них проявляются по сути одни и те же закономерности. Например, можно понять многое из жизни людей, изучая как образуются химические связи, а из жизни народов — изучая, скажем, астрофизику или биологию. Постигая каждую следующую науку, каждый новый предмет, мы по сути всего лишь учимся думать, все глубже и глубже постигать отношения и взаимосвязь вещей, противоречия между ними. А атомы или звезды — это всего лишь материал для постижения общих законов мышления. Поэтому если абстрагироваться от конкретного изучаемого предмета, и взять все эти вещи и отношения в чистом виде, в виде чистых мыслей, то мы получим науку о мышлении — логику, или, если взять шире, философию.
Знание философии (не истории философии, а именно философии — например, диалектической логики Гегеля) так же важно для программиста, как и знание языка и основных техник программирования. А порой, даже важнее. Ведь чтобы написать хорошую программу, нужно прежде всего составить правильную модель предметной области, для которой разрабатывается программа. Есть хорошая модель — будет и хорошая программа. Только так. Чтобы составить модель, нужно понять предмет, осмыслить его. Чтобы осмыслить предмет, нужна философия.
Все мы пользуемся на интуитивном уровне такими философскими категориями, как движение, количество, качество, сущность, понятие. Но многие ли из нас смогут сейчас сказать, что они означают? А кто сможет вывести понятие из сущности? Кто знает наверняка, всё ли находится в движении, или есть что-то, что не изменяется? То-то и оно. А ведь если знать, что такое сущность сама по себе, можно гораздо легче и быстрее определить сущность и любого конкретного предмета.
Получается, что хороший программист не может быть только программистом. Парадокс — *чтобы стать хорошим специалистом, нужно перестать быть специалистом*.
Итак, если подытожить, то у программиста только два пути: налево пойдешь — богатому быть, направо пойдешь — убитому быть смириться и мучиться, как все, копаясь в legacy-коде, или потратить долгие годы на самообразование и наработку техники разработки качественного кода.
У менеджеров аналогичный выбор: или терпеть плохой код и постоянно сдвигать сроки релиза, или заранее заложить больше времени и тратить его на периодический рефакторинг кода в надежде однажды получить достойный проект, а потом, может, даже сделать из него фреймворк.
Однако, есть и третий вариант — взять готовый фреймворк, дать своим разработчикам неделю-две в нем разобраться, а потом клепать игры по шаблону и горя не знать. Тут на ваше рассмотрение как раз и представлен процесс разработки такого фреймворка — результата многочисленных переписываний и поисков оптимального баланса между универсальностью, гибкостью и простотой.
Комментарии (16)
samoreklam
03.07.2022 13:52+2Но одно дело найти ошибку, и другое — ее исправить так, чтобы не
появились другие баги. На это можно потратить еще столько же часов. А то
и дней.А ещё можно потратить на ПОИСК бага, несколько месяцев.
И так его и не найти!
SpiderEkb
03.07.2022 18:01+1Таким образом, вопрос: качество или скорость переходит в проблему: хороший, но вечно незаконченный проект или хоть как-то, но работающая программа. Любой менеджер как реалист, естественно, выберет второе.
Как только менеджер начнет терять деньги от "как-то работающей программы", его мнение резко поменяется.
На самом деле, правильно было замечено что
Конечно, следовало бы поступить по-иному. Если есть достаточный опыт и теоретическая подготовка, а проект перспективный, не одноразовый, то нужно сначала хорошенько разобраться в теме, выработать качественное решение, а потом уже на основе его серийно делать проекты.
Для начала берем BRD (причем, оно тоже должно быть согласовано) от заказчика и на его основе делаем архитектурное решение. Потом его осуждаем. Когда архитектура утверждена, на основе BRD и архитектуры делаем FSD. И дальше уже следуем ему, не отвлекаясь на "а вот мне тут еще классная фича в голову пришла..."
Все, что пришло в голову пишем в todo для дальнейшего обсуждения.
Ну и про оценку времени тоже не забываем. Любая задача должна быть оценена - столько-то времени на аналитику, столько-то на разработку, столько-то на тестирование.
В общем, в разработке должен быть системный подход. А не допускать до проекта "юношей пылких со взором горящим", которые сразу хватаются за клавиатуру и начинают "творить" без предварительной подготовки. В 99.99% случаем это пустая трата времени и ресурсов.
Любой проект должен "созреть" в голове. Даже если это личный пет-проект. Дать ему "устаканиться", представить все в голове от начала до конца и потом уже планомерно реализовывать в том объеме, который ясно себе представляете. А что пришло в голову по ходу пьесы - оставлять для дальнейшего развития.
merkator2160
03.07.2022 18:47Мои мысли читаешь. Ты меня опередил с написанием статьи. Низкий плклон и благодарность от всего сердца!
Red_Nose
03.07.2022 22:24Т.е. достаточно древнее "выбери два из трех: качественно, дешево, быстро" автор не знает ?
Aleksandr-JS-Developer
05.07.2022 11:56+1Знает. Про это и написана статья. Все выбирают "дешево и быстро". Всегда. То, что описано в статье называется "технический долг".
Небольшое его количество и постоянный мониторинг - это золотая середина.
А вот когда его много - он съедает и скорость и бюджет, оставляя только не качественность.
Особенно им брезгают при проектах "взял, запилил модуль, через неделю отдал".
Я думаю, что в наличии большого тех. долга виноват менеджер полностью.Особенно, если он может влиять на кадры. Отмазка в духе "были одни джуны, они нагородили" не работает. Понятное дело, что джуны накуролесят. Или ты думал, что можно платить специалистам в пять раз меньше и ожидал качественный результат?
Найми тех лида, а он уже подберет команду. Разработка (особенно игр) - это ДОРОГО и ДОЛГО. Всё. Нормальный продукт по другому и не происходит
APXEOLOG
03.07.2022 22:45Однако, есть и третий вариант — взять готовый фреймворк, дать своим разработчикам неделю-две в нем разобраться, а потом клепать игры по шаблону и горя не знать
Вот только игры "по шаблону" не особо интересны. Если у разработчика клона есть оригинальные идеи - зачастую он упрется в ограничения фреймворка. Если у него нет оригинальный идей - получится унылый клон, в который никто не будет играть.
Чем специфичнее фреймворк, тем больше шанс удариться в лимиты. Чем больше возможностей дает фреймворк - тем он сложнее и больше шансов сделать плохо и получить все тяготы, которые описаны в статье
GospodinKolhoznik
04.07.2022 09:47+1Вот только игры "по шаблону" не особо интересны.
Разве это так? Все играют только в стандартные шаблонные рпг, шутеры, счастливые фермо-крафтеры и чуть пореже в стратегии, адвенчуры и гонки. Ну и ещё "дорогие любители футбола" играют в дорогие футбольные симуляторы, куда же без этого.
А вот в нестандартное люди не играют. Поругать шаблонные игры все горазды, а взять и купить действительно нестандартную игру желающих мало. Я уверен, что гейм девелоперы с удовольствием бы делали новые уникальные игры, но не делают этого просто потому, что в них никто не будет играть. Ну правда же!
В 80е, когда жанры ещё не устаканились и люди играли просто в разные игры, и разработчики решались на совершенно отчаянные по сегодняшним меркам проекты. Большинство игр того времен были платформерами, но если игра не платформер, то скорее всего она была с уникальной игровой механикой и совершенно крезёвой задумкой.
Сейчас и близко такого нет. Сейчас нестандарнтыми и уникальными играми называют шаблонные проекты, в которых чуть-чуть что то одно поменяли. Да и это делают очень редко. Почему? Да потому что пользователи не хотят никаких изменений, их и так все устраивает. А в игры с новыми уникальными механиками надо долго врубаться, заморачиваться, учиться в них играть. Этого никто не хочет.
Ситуация как с Голливудским кино. Все его ругают, называют тупым, пустым, бездарным, но смотрят только его. И даже когда сам Голливуд пытается чуть-чуть приподнять планку и снять что то более серьезное, зрители такой фильм просто сливают, обрекая на кассовый провал.
APXEOLOG
04.07.2022 10:27+2Разве это так? Все играют только в стандартные шаблонные рпг, шутеры, счастливые фермо-крафтеры и чуть пореже в стратегии, адвенчуры и гонки
Это именно так. То о чем говорю я - это унылые клоны, которые отличаются сменой моделей и текстур и (буквально) парой новых фич. Вы, скорее всего, о них даже и не слышали - именно потому, что они никому не нужны и никогда не становились хоть сколько-либо известными или популярными. Бесчисленные клоны майнкрафта, шутеры по шаблону на юнити с купленным паком моделек и т.д., самые успешные из них можно найти в недрах стима с ценой в 10р и сотней инсталлов. На мобильном рынке это еще более заметно.
То, во что массово играют сейчас люди - это игры, сделанные, как правило, на своих собственных движках. Ну или взят существующий мощный графический движок (Unreal / Unity), а все остальное самописное
GospodinKolhoznik
04.07.2022 12:18+1Вы говорите, что популярные игры оригинальны и уникальны. Я этого не вижу. Абсолютно все популярные сегодня игры это клоны других игр, которые в свою очередь были клонами клонов и т.д. Какие то там отличия надо просто под микроскопом искать.
Да, майнкрафт был уникальной игрой, когда появился в 2009 году. В игру продолжают играть уже 13 лет. И за эти 13 лет не появилось ни одной популярной новой игры. Новой в смысле с новой игровой механикой и концепцией.
В 80е концептуально новые игры появлялись почти каждый день. Да, была проблема - все они были абсолютно неиграбельное говно. Но они были реально уникальные и по настоящему самобытные. Но тогда вообще не было хороших игр из-за технических ограничений компьютеров тех лет, и люди часто брали игры именно за уникальность, потому, что как шаблонная так и оригинальная игра будут одинаково убогими, но оригинальная хотя бы как то интересна за счет своей необычности.
Сейчас уже не так. Люди предпочитают играть в гарантированно хорошие шаблоны, нежели в неведомо что. Сейчас тоже появляются действительно новые игры. Но все они совершенно непопулярны. Даже когда их делают бесплатными, никто в них не хочет играть. По ряду причин - потому что игровая механика хоть и уникальная, но унылая, потому что бюджет околонулевой и графика отвратительная и просто потому что люди не хотят ничего нового ибо не хотят меняться.
APXEOLOG
04.07.2022 13:23+1Вы говорите, что популярные игры оригинальны и уникальны
С точки зрения разаботки (а статья именно про это) - да. AAA-тайтлы вообще целиком на своих разработках, остальные, максимум, заимствуют один из топовых графических движков.
Абсолютно все популярные сегодня игры это клоны других игр
Это вопрос философский и можно долго спорить на этот счет. Что есть уникальность, где границы жанров и т.д.
Да, майнкрафт был уникальной игрой, когда появился в 2009 году
Ну не знаю. Я вот например не фанат майнкрафта. Знаю достаточно песочниц с большим кол-вом фич и контента, которые появились задолго до. Единственное, что до майнкрафта никто не делал (во всяком случае я не в курсе) - воксели.
И за эти 13 лет не появилось ни одной популярной новой игры
Ну не знаю, Destiny и сессионные пве шутеры, Hearthstone и засилье ККИ, Fortnite с его "царь горы", Rust и session-survival-sandbox игры, популярность автобаттлеров - довольно много веяний приходило и уходило за эти годы. И это только то, что я помню. Можно, конечно, сказать, что это все тоже клоны - раз есть автомат, значит клон шутера и т.д. Но я рассматриваю игры с точки зрения концепта гейм механики, а не сеттинга
LaRN
04.07.2022 13:23+1А еще есть вариант того ,что выбранный фреймворк как и "самописный" перестанет попадать в видение проекта и получим те же сложности, но уже в плоскости смены фреймворка.
Тут наверное основой вывод - это то, что перед тем как сесть писать код нужно все хорошо спроектировать, но это требует много времени, поэтому так мало кто делает. Выбирают эволюционный подход, но в ходе эволюции не все решения выживают.
Aleksandr-JS-Developer
05.07.2022 18:25не все решения выживают
Это не страшно. Страшно то, что команда продолжает осознанно заниматься некрофилией с этим решением дальше.
dkuzminov
04.07.2022 00:26+2В одной книге про чистый код прочитал золотые слова: "For decades of using the terms programming languages, we thought that they were languages to communicate our ideas to the machine, so it can run our programs. We were wrong. That's not the truth, but part of the truth. The real language behind programming languages is to communicate our ideas to other developers."
Проблема не в том, что "начали исходя из одних предположений, а потом все изменилось." Нет, она глубже. Проблема в том, что большинство участников проекта в принципе плохие инженеры.
На эту тему я могу распинаться долго, но пока остановлюсь на одном аспекте: именование сущностей. Классы, функции должны в своем имени содержать контракт на то, что они собой представляют, как их использовать, каковы планы автора на дальнейшее расширение функционала. Благодаря грамотному имени и интерфейсу становится возможной идиома "разделяй и властвуй": во время ревью можно сказать, соответствует ли реализация метода его имени и сигнатуре, и если нет, то это можно считать ошибкой. А в вызывающем коде можно сделать предположение о функционале вызываемого метода только по его названию. Но беда в том, что разработчики сами плохо понимают, что именно они пытаются сварганить, а потому сгребают пыль под ковер, давая сущностям "обобщенные" имена вроде "compute", "process", и т.д. В итоге такой код становится легаси даже не с написания первой строчки, а с момента найма сотрудника.
Закончу еще одной цитатой, которую приписывают то Фейнману, то Эйнштейну: "Если вы что-то не можете объяснить 6-летнему ребёнку, вы сами этого не понимаете." Если вы сами себе не в состоянии объяснить, что вы делаете, дав сущностям подходящие имена, а в коммит-месседжах четко описав идею, которой вы руководствуетесь -- то не надо валить вину за дальнейшие проблемы на "изменившиеся обстоятельства".Deosis
04.07.2022 07:09Помимо названия функции, огромную роль играют типы входных и выходных параметров.
В Хаскеле по ним вообще поиск сделан.
dkuzminov
04.07.2022 07:27+1Ну я говорил не только об именах, но и об интерфейсах и сигнатурах. При этом искусство называть сущности своими именами вызывает меньше разногласий, чем, допустим, порядок аргументов.
Apoheliy
А ещё есть дисциплина Управление Проектами. И из неё выясняется, что выборов намного больше, чем описано в статье. По мне лучше объединить введение с разделом 2 и даже 3: получится содержательнее.