Лучше самому изобрести колесо, чем ездить на арендованном квадратном
Так получилось, что загруженный в меня годами разработки опыт привел к нигилизму и отрицанию общемировых ценностей. Например, я ненавижу демократию, самое первое запротоколированное проявление которой привело к решению распять нахрен одного там назаретянина (но сейчас не об этом). Я отрицаю пользу IDE, необходимость развития языков программирования, целесообразность существования паттернов и еще много достижений цивилизации по остаточному принципу.
Зато я являюсь ярым сторонником велосипедостроения. В подавляющем большинстве ситуаций лучше спроектировать и реализовать свой велосипед с перламутровыми пуговицами, чем пытаться приварить оные к выкидышу китайского велосипедопрома. Почему-то среди моих коллег принято относиться к собственным реализациям чего угодно — пренебрежительнее, чем к невнятной библиотеке версии 0.0.1
, написанной албанским стажером три года назад по пьяни.
Бесчисленное количество раз за мою карьеру я слышал пренебрежительный вердикт «свой велосипед» в самых разных ситуациях: от нежелания тянуть в проект очередной лефтпад — до ультимативных решений, выходящих далеко за рамки существующих на рынке. Я не призываю, конечно, писать для каждого проекта свой движок реляционной базы данных, но уже адаптер к ней — нуждается в тщательном анализе перед использованием. Стратегия «найти библиотеку по ключевым словам и втащить в проект» — ничем не лучше копипасты со стековерфло (или простихосподи чатжопотэ).
Если разработчик уровня выше стажера считает, что какой-то хрен из интернета уж точно напишет случайный кусок кода лучше него — это не программист, это самозванец, его надо гнать из команды с волчьим билетом.
Слышу, слышу вас, люди-всегда-использующие-библиотеки! Слышу ваши возражения, да и знаю я их наизусть уже. Их обычно три.
① Сроки не резиновые
Конечно. Поэтому нужно семь раз подумать перед посещением моэля. Что вашей команде обойдется дороже: потратить неделю прямо сейчас на реализацию того, что нужно именно вам и вашему проекту, или месяцы сопровождения библиотеки общего назначения, медленно решающей отдаленно похожую на вашу задачу. Разумеется, существуют библиотеки, написанные умными людьми (желательно, теми, с которыми вы лично знакомы, но и простого знания имени иногда достаточно). Это не проявление authority bias’а, отнюдь, это кредит доверия: умные люди крайне редко пишут и выкладывают на всеобщее обозрение плохой код. Библиотеки, написанные core team языка — всегда можно тянуть с свои проекты без стеснения: вы уже доверились им с самим языком, доверьтесь и тут (и то, мой личный опыт показывает, что в трех из четырех случаев вам придется слать PR в эти библиотеки, чтобы они покрывали и ваши corner cases).
Но если библиотека написана каким-то чуваком из Оклахомы, про которого известно только то, что его ник на реддите — gray_pussy_2008… Ну, хотя бы имеет смысл заглянуть в тесты, пробежаться по исходникам и — зачастую самому — прогнать бенчмарки.
② Тысяча мух не может ошибаться
«У библиотеки тысяча звезд на гитхабе, люди гоняют её в хвост и в гриву в продакшенах, все ошибки давно найдены и починены, а твой велосипед завтра не удержит нагрузку!» — знакомо? Так вот, это туфта. «Все счастливые семьи похожи друг на друга, каждая несчастливая семья несчастлива по своему», — сказал однажды Лев Николаевич по другому поводу, но и там всё закончилось безвременной кончиной проекта на рельсах.
Ваш corner case будет не таким, как у автора и пользователей библиотеки. Поверьте нашему с Джоэлом опыту, никто не тестировал этот код на польской версии виндоуз. И даже когда вам удастся локализовать проблему и укрыть тестами неподатливый кусочек кода — как вы собираетесь его чинить, если ограничение на четыреста капель валерьянки прибито гвоздями, а вам нужно четыреста две?
Свой код проще прогнуть под изменчивый мир.
③ Почему ты думаешь, что твой код будет лучше
Ну, кхм… Во-первых, потому что я умею писать код. Если бы это было не так, я бы работал поваром. Во-вторых, тут не конкурс по измерению длины кода. Возможно, даже, первая итерация будет и не лучше. Но внесение починок, правок, добавлений, испрошенных коллегами — будет на три порядка быстрее. Ваш код проще править, чем тот, который вы вчера выкачали из гитхаба и добавили в зависимости.
И, в-третьих (и в-самых-главных) — внутренний код не поломается со следующим обновлением компилятора, остальных библиотек и прочих обвязок (то есть, он, конечно же, поломается — но и починится довольно легко и быстро).
А еще, если у кого-то внутри команды появятся вопросы по использованию, — вы сядете вместе перед экраном и быстро состряпаете тот API, который будет удобен всем. Не ломая обратную совместимость (если вы не отщепенец, которого надо прилюдно сечь плетьми на центральной площади).
У велосипедов, помимо перечисленных выше преимуществ, есть еще одно, на длинных отрезках пути даже более существенное, — создание собственных велосипедов прокачивает кунфу вашей команды в сотни раз сильнее, чем использование чужих. Тут уже не удастся отделаться подсказкой любимой среды разработки для выбора метода, или спросить LLM. Если вы хотите сделать что-то действительно хорошо — придется делать самому, продумывая детали и вникая в тонкости.
И оно всегда окупается.
Когда-то давно я прочитал блистательный текст Лекси Кинг «Parse Not Validate» и прошерстил экосистему на предмет библиотеки, которая бы перевела этот текст в код. Самым перспективным кандидатом — оставалась Ecto, которую я и так везде использовал для валидации. Но меня раздражали три вещи: это всё еще была валидация вместо парсинга, она требовала слишком много бойлерплейта и — основное — я не видел элегантного способа прикрутить к ней генерацию данных для property-based тестирования. В общем, я написал свою библиотеку estructura, которая занималась ровно этим: парсингом слабоструктурированных данных во вложенные структуры эликсира.
Как всегда в таких случаях, после релиза в OSS, я собрал все команды на небольшой Tech Talk, рассказал о преимуществах и услышал в ответ вполне ожидаемое «а чем тебе, пёс, схемы экто, проверенные миллионом мух, не угодили?». Ничего другого я не собирался услышать, поэтому лишь загадочно улыбнулся.
Спустя месяц нам потребовались динамические вложенные структуры. К вечеру я их прикрутил и выпустил минорный апдейт (API не изменилось вообще, я с первого дня использовал Access
). Наутро наша команда их попробовала, к вечеру — притащила в мастер. Каким количеством костылей пришлось подпереть экто, чтобы прозрачно парсить данные на третьем (пятом, десятом) уровне вложенности — я повидал на многочисленных кодревью соседей.
При этом экто — в сто раз мощнее и в триста раз провереннее моего велосипедика. Зато он решает наши задачи гораздо лучше блестяще зарекомендовавшего себя в индустрии монстра. Я с ними и не думал соревноваться. Просто этот шуруп оказалось удобнее закрутить крестовой отверткой. Помните об этом, когда вам снова скажут: «Фу, это велосипед, возьми вон библиотеку, которая делает это!». Если она действительно делает ровно это, вы проглядели код и тесты, запустили бенчмарки и вас всё устроило — берите, не пожалеете. Но если хоть один тест из предложенных выше не зазеленелся — не берите. Лучше постройте свой велосипедик. Или сразу веспу.
Удачного велосипедостроения!