пятница, 21 сентября 2018 г.

[prog.thoughts] Мнение пациента с хроническим NIH-синдромом: плюсы и минусы самодельного внутреннего инструментария

Так уж получилось, что я являюсь паталогическим велосипедостроителем. Отчасти тому виной моя собственная натура, ну вот нравится делать что-то свое или же переделывать чужое под себя. Отчасти потому, что в программирование я пришел в начале 90-х, да еще в СССР, который был сильно изолирован от остального мира в области ИТ. Поэтому, просто из-за отсутствия инструментария, приходилось многое делать своими руками.

Как бы то ни было, так уж случилось, что за время своей работы в ИТ мне довелось создать несколько инструментов для разработчиков, которые использовались для создания прикладного софта. Созданный на базе моих инструментов работал годами и годами же находился на сопровождении. Ну, скажем, в 2002-ом году мной были сделаны первая версия SObjectizer-4 и встраиваемая ООСУБД ObjESSty, на базе которых затем был сделан агрегатор SMS/USSD сообщений. Этот агрегатор, как оказалось, до сих пор работает, прокачивает пару тройку десятков миллионов сообщений в сутки, что дает более полумиллиарда сообщений в месяц. Часть компонентов все еще работают именно на SO-4 и ObjESSty. Часть компонентов была написана уже на SObjectizer-5. Но, опять же, возраст этих "новых" компонентов так же измеряется годами.

Да, все это был софт, про который нигде не рассказывали, с ним не сталкиваются миллионы пользователей напрямую, как это происходит с продуктами известных компаний, вроде Microsoft, Google, Yandex и иже с ними. Так что вам, читатель, решать, интересно ли вам мнение велосипедостроителя, работавшего в noname-компаниях и принимавшего участие в проектах, о которых вы никогда не слышали и не услышите.

Но т.к. этот блог был создан для того, чтобы я мог свободно говорить то, что хочу, то все-таки выскажу свои мысли на тему того, насколько выгодно или невыгодно компании создавать и развивать свой внутренний инструментарий. Что может быть интересно тем, кто работает не в Google или Yandex-е, а в продуктовых конторах поменьше, с другими штатами, бюджетами и возможностями. Речь про продуктовые компании, т.к. про то, как со внутренним инструментарием дела обстоят на аутсорсинговых галерах я понятия не имею.

Плюсы

Итак, начнем с плюсов. Точнее, с плюса, т.к. с поиском остальных достоинств дела обстоят несколько сложнее.

Главное достоинство собственного инструментария в том, что этот инструментарий заточен под вашу задачу. По крайне мере должен быть заточен. Благодаря этому вы должны сильно экономить на количестве кода, который вам нужно написать. Грубо говоря, если без специализированного инструмента вам нужно написать 150 строк кода, то со специализированным инструментом вы пишете 15 строк кода. Ну или хотя бы 50.

Чем меньше кода, тем лучше. Количество кода самым прямым образом трансформируется в сроки и деньги. Грубо говоря, если вам нужно написать 30K строк кода при средней производительности одного разработчика в 100 (сто) отлаженных строк в день, то у вас один расклад по срокам. Скажем, команда из 5 человек напишет эти 30K строк за 60 рабочих дней, что означает 3 месяца работы. Сами можете прикинуть, сколько в ваших условиях стоит работа команды из 5 разработчиков в течении 3-х месяцев (например, если взять бюджетные $25 в час, то получаем 60*8*25*5=$60K). А теперь представьте, что вы уменьшаете количество кода, который вам нужно написать, раза в три. Вместо 30KLOC вам нужно всего 10KLOC. Соответственно, вместо $60K вам оказывается достаточно всего $20K.

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

Ну, например, вы можете обнаружить, что в вашем продукте при работе с СУБД возникает два или три сценария, которые используются чаще всего. Соответственно, вы создаете какую-то нашлепку над вашим ORM (или вашим инструментом для работы с СУБД, если ORM вы не применяете), которая будет позволять вашим разработчикам использовать один из этих сценариев буквально одной-двумя строчками. Тем самым вы снимаете с разработчика часть головной боли, но его основная работа никуда не исчезает: его задача -- это взять откуда-то данные для СУБД, подготовить их к записи, дернуть в нужный момент вашу нашлепку, затем обработать результат записи в БД. Эта задача упростилась, да, но ее все равно нужно будет делать вручную.

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

В общем, вы действительно получаете ряд выгод, но суммарный выигрыш, наверное, будет измеряться десятками процентов. Тем не менее, выигрыш в 20% -- это совсем не так мало. И оно того стоит.

Минусы

Естественно, что бесплатный сыр бывает только в мышеловке. Поэтому за выгоды, которые дает вам ваш специализированный инструментарий, приходится чем-то платить. Чем именно?

Время на разработку инструмента

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

Каков масштаб этих затрат? Ну, представьте себе, что разработчик потратил неделю на создание инструмента и затем этот инструмент в течении года использовался без каких-то серьезных доработок и добавления в него нового функционала. Скорее всего в течении года еще неделя была потрачена в буквальном смысле туда-сюда. Где-то несколько часов на то, чтобы разобраться с одной проблемой, где-то день на поиск и устранение хитрого бага, где-то полдня на то, чтобы пропрофилировать и устранить явный косяк с производительностью в каком-то особом случае. Где-то полдня на то, чтобы написать хоть какое-то README+FAQ и избавиться от самых распространенных и простых опросов.

Итого две недели можно считать смело. Опять же, при бюджетной оценке в $25/h получаем 10*8*25=$2K. И это за очень простой инструмент (всего неделя для первой полнофункциональной версии), без его серьезных доработок в последствии и при очень низком рейте (люди, которые имеют опыт и квалификацию для создания нормального инструментария будут стоить дороже).

Документация и обучение

Многие ли из вас видели внутренний инструментарий, разработанный для собственных нужд, который был бы снабжен хорошей и актуальной документацией? Причем для нормальной документации нужно иметь, хотя бы, API Reference Manual и Developers Guide. Если с первым еще можно хоть как-то справиться за счет Doxygen-подобных инструментов, то вот второе нужно отдельно и целенаправленно писать отвлекшись от программирования.

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

Качество

Качество внутреннего инструментария -- это отдельный и неоднозначный вопрос. С одной стороны, если разработкой инструмента занимается опытный разработчик, то качество будет точно лучше, чем код, который в отсутствие инструмента рядовой разработчик наколбасит прямо на месте. С другой стороны, если инструмент будет применяться в разных сценариях, то точно рано или поздно в нем будут обнаруживаться проблемы. А вот насколько быстро и хорошо они будут устраняться... Тут зависит от многих условий, например, если проблема выявилась во время аврала перед очередным релизом, то запросто может быть налеплена заплата или вкорячен какой-нибудь workaround. Ну просто в качестве временного решения. А временное имеет свойство жить долго.

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

Bus-factor

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

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

Насколько новое видение совпадет со старым и насколько симбиоз новых и старых идей окажется жизнеспособным и удобоваримым -- это большой вопрос. А для владельца проекта -- большой риск.

Как же быть?

Из написанного выше может сложиться впечатление, что разработка внутреннего инструментария -- это дело невыгодное и рискованное. Что близко к истине, но все-таки не совсем так :)

Думаю, что более правильно было бы сформулировать так: при разработке собственного внутреннего инструментария расходы на его развитие и применение будут расти со временем. Как и риски возникновения каких-либо проблем. Т.е., затраты на собственный лисапед в первые три года его использования будут ниже, чем затраты через 10 или 15 лет.

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

Как это можно сделать?

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

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

Заказывать разработки/доработки на стороне выгоднее, т.к. в этом случае отсутствие документации или недостаточное покрытие тестами становятся уже не вашими проблемами, а проблемами исполнителей ;)

В-третьих, если вы все-таки решились на собственную разработку, то постарайтесь как можно быстрее разделить стоимость владения этой разработки с другими людьми/компаниями. Т.е. открывайте свой инструмент как OpenSource и, если это еще кому-то нужно, то вы будете получать либо готовые Pull-Request-ы, либо новые идеи и соображения (которые так же могут стоить немало). Даже bug-report-ы от сторонних пользователей -- это большой плюс, т.к. вы можете обойти собственные же грабли, на которые уже кто-то наступил.

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

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

В общем, разработка своего инструментария -- дело непростое и недешевое. В этом и есть основной посыл данного поста.

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

К чему это все?

Наш мир постоянно меняется. Вот, скажем, в середине 1990-х OpenSource как таковой был. Но его роль была не так заметна, как сейчас, спустя всего 20 лет. Поэтому то, что было выгодно раньше, может быть невыгодно сейчас.

Свой собственный внутренний инструмент -- это было необходимостью в 70-х и 80-х, затем было приемлемым решением в 90-х. Но после 2000-х это уже не так. И даже если вам нужен специализированный, заточенный под ваши специфические нужды, инструмент, то это вовсе не означает, что вы должны делать это своими силами.


PS. Понятное дело, что все это откровенная джинса. Проплаченная мной :)

Комментариев нет: