Ваш код сегодняшний, коллега
Напоминает даунхил:
Среди деревьев и гов#@ща –
Велосипед и костыли ...
Народная мудрость
Пару лет назад я сделал небольшой цикл заметок о паттернах поведения: Технический долг, Синдром рефакторинга и Эффект второй системы. Пришло время обсудить еще один, наверное, самый известный и популярный паттерн поведения – синдром «Придумано не нами» (NIH, Not Invented Here).
Мало кто любит чужой код. Букв в нем обычно много, докапываться до сути сложно, читать между строк получается не у всех, а читать мысли автора без хрустального шара и крови ягненка пока вообще не научились. Другое дело, пилить что-то с нуля: система развивается поэтапно, ты знаешь, какие были компромиссы на каждом шаге разработки и понимаешь, почему было принято то или иное решение. Ты учишься, поскольку информация о системе аккуратно складывается в голове в цельную картину. Но как только на твоем месте оказывается другой человек, то он, почему-то, не ценит твои усилия и стремиться все выкинуть и переписать заново.
У «забить на существующее и сделать по-своему» есть несколько причин.
Во-первых, разработка с нуля – это lot of fun! Сделать свою конкурентную коллекцию, собственный менеджер по обмену сообщениями, или собственный ORM, - это же интересно! Это действительно классный способ узнать что-то более детально. Вот, правда, поддерживать чужие творения подобного рода – удовольствие ниже среднего.
Во-вторых, ты можешь не знать о существовании готового решения. Если ты не знаешь о наличии готовых библиотек по парсингу деревьев выражений и даже не подозреваешь о существовании деревьев выражений в .NET, то очевидно, что ты будешь городить свое собственное решение. Пример утрирован, но часто именно ограниченность нашего кругозора приводит к использованию неподходящего инструмента или изобретению собственного.
В-третьих, повторное использование чужого решения может быть просто сложнее, чем разработка своего собственного. Главная сложность повторного использования в том, что оно должно быть простым! Никто не захочет использовать чужой код, если для этого нужно будет форкнуть три репозитория, скачать две тулы для их сборки, и потом еще разбираться в чужих граблях. Минимальные проблемы использования, обновления или диагностики ошибок, и прагматизм закончится даже у самого здравомыслящего разработчика и все, привет, еще один велосипед!
В-четвертых, ты можешь думать, что у тебя получиться лучше. Никто не может написать нормальную библиотеку конкурентных коллекций, а ты сможешь. Никто не может реализовать свой собственный Key-Value Store, но только не ты! Тут есть два варианта: ты изучил разные реализации, и четко понимаешь, в чем у них проблемы и как от них избавиться. В этом случае ты просто не берешь в новое решение весь багаж накопленных ошибок из старых решений, а начинаешь с чистого листа. Ты не используешь готовый код, но точно используешь накопленный тобой и другими опыт. В итоге может получиться что-то хорошее, полезное и для тебя, и для других (Roslyn – отличный пример такого подхода).
Обычно же все происходит несколько иначе: ты слышал, что кто-то когда-то игрался с неизменяемыми коллекциями и что-то с ними было не так. И даже не разбираясь с существующими проблемами готовой библиотеки, ты пишешь свою реализацию. Обычно получаются те же яйца, вид в профиль. Просто ты знаешь, где подставить костыль, чтобы решение не развалилось полностью.
Повторное использование vs. Изобретение велосипеда – это типовой компромисс, на который идут индивидуальные разработчики, команды разработчиков и целые компании. В Microsoft есть 4 разных системы для сбора и анализа телеметрических данных, десяток клонов анализаторов IL-кода и сотни или даже тысячи реализации коллекций всех мастей. И так в любой компании.
Довольно сложно найти правильный баланс между «использовать повторно и сделать хорошо всем» vs. «решить свою проблему здесь и сейчас». Синдром «изобретено не здесь» можно рассматривать как частный случай проблемы «реюз компонента» vs. «дублирование кода». В одном случае лучше продублировать код и не вводить лишних связей, а в других лучше обобщить, сделать повторноиспользуемый компонент и всем жить дружно и счастливо. Да, это сложно, но ведь возможно же.
Распространение NuGet-ов и других менеджеров пакетов упрощают потребление сторонних компонентов и делают полезное дело в плане повторного использования. Но это интересное сочетание программистского пессимизма («все делают всё плохо») и оптимизма («но я сделаю всё хорошо»), никогда не убъет синдром “Not Invented Here” полностью. Что, может быть, не так и плохо;)
Синдром, собственно, в чём заключается? В нелюбви чужого кода? Или во "всё выкинуть и переписать"?
ОтветитьУдалитьВо "всё выкинуть и переписать". Нелюбовь к чужому коду - это одна из причин, почему такой подход столь популярен.
УдалитьПонял, спасибо. У меня с этим другая боль: смотрю вокруг, и там, где мне кажется, нужно взять готовое - там пишется своё, а там, где наша просто самим всё выписать - берётся что-то и обкладывается костылями. 😞 То есть проблема не в чужом коде, а в том, как он используется (или не используется).
Удалить+100 500.
УдалитьЗачастую это любовь к написанию своих велосипедов как раз приводит к тому, что появляются отличные новые библиотеки и фреймворки. Если бы все использовали только чужие наработки прогресс в ИТ остановился бы, разве не так?
УдалитьНу, ИМХО, все ж ведь несколько сложнее.
УдалитьКогда начинает писать свое собственное волшебное творение человек, без соответствующего бэкграунда и опыта написания чего-то подобного, то очень редко получается что-то хорошее.
Когда Линус брался за Git он четко знал, что ему нужно, и как это можно сделать. Но если я бы взялся сделать что-то такое же, то результат был бы несколько иным...
Речь об отсутствии крайностей, только и всего.
А не случалось с вами так, что смотря на код, появлялось огромное желание переписать все это, а потом, из за интереса, посмотрев по history, мы обнаруживаи, что это наше творение, давности пару лет? Так, что причинами синдрома рефакторинга или эффект второй системы зачастую не только субъективны но могут быть и объективны. И в это есть рациональное зерно, это индикатор, что ты професионально рос.
Удалить@Hamlet: да, если ты все еще гордишься кодом многолетней давности, то тут есть два варианта: код нереально хорош или ты перестал развиваться.
УдалитьВ синдроме NIH надо учитывать и другую сторону! Например, почему если коллекция уже написана, то делал это опытный зубр, а не студентик-индус за день до сдачи проекта? Где "штамп качества"? :) Или вот готовый класс есть, но такой "развесистый всемогутер", что его использование превращается в гемор уже на стадии чтения примеров.
ОтветитьУдалитьNIH - это не только синдром личных амбиций, но и показатель качества существующего кода. ХОРОШИЙ код никто даже не подумает переписывать. Если код - говно, у него тут же находятся десятки клонов и новых версий.
Штамп качества обычно идет рядом с самой библиотекой. Например, если что-то есть в BCL, то это говорит об определенном уровне качесвта. Но это, например, не касается NPM библиотек, которые вполне могут тримать строку и больше ничего.
УдалитьИ я не думаю, что дело только в качестве: хороший код, но чужой будут переписывать аж бегом, особенно тогда, когда с хорошестью идет еще и определенная сложность.
Ну и вообще, хорошесть - это же довольно многоликая штука. В чем вообще она заключается? Легко использовать? Много функций? Хорошая документация? Легко найти ответ на stackoverflow? Высокая производительность? Обычно не все аспекты хорошести есть даже у самых популярных библиотек...