Pull to refresh

Comments 74

Дело вкуса, иногда библиотеки очень здорово экономят нервы и это к ним и располагает )
особенно если они OpenSource и есть возможность их «подпилить» под нужды проетка — регулярно пользуюсь такой вот схемой. Ну и соответсвенно весь код «подпиленных» библиотек — так же открытый.

Для собственной разработки очень сомнительные допущения — «Члены команды знают как все работает в деталях» и «Максимально производительное решение».
Мое мнение — делать самому нужно только то, что непосредственно является функциональностью продукта, остальное пусть делают другие люди.
Особенно проблемное «Члены команды знают как все работает в деталях» — эти члены могут в любой момент уволиться по куче разных причин
Как я видел — на больших проектах команда хуже знает свои библиотеки, чем сторонние.
В своей досконально разбирается хорошо если десяток программистов, непосредственно участвовавших в создании. Остальные видят только примеры использования. При этом, в отличие от — документации как правило нет даже в зародыше, и даже в лучшем случае она слабо покрывает описываемый функционал.
Если же библиотека переросла этот этап и стала полноценным продуктом, имеющим хождение по всему миру (привет, open source) — речь уже не идет о домашней самоделке.
и на нанятых «в замену» сваливается куча код, где если и есть комментарии, то зачастую вида
«не трогать, т.к. .........»
Даже не увольнение.
Зачастую даже полностью твоя разработка: через полгода ты уже и половину нюансов помнить ее реализации не будешь или придется вспомнить упорно, если нет подробных комментариев по коду или документации.
Изобретать колесо следует в двух случаях:
1. Колеса не существует
2. Все имеющиеся колеса — квадратные
А если абсолютно круглого колеса нет, а есть в форме правильного многоугольника с большим количеством граней, что вроде бы уже и почти круг, но все таки еще немножко трясет когда едешь.

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

Я к тому, что если я работаю над какой-нибудь мега ультра латенси системой, где мне каждая миллисекунда дорога, то приходится задумываться, а не будет ли лучше если я вместо меганавороченного кэша буду использовать простую HashMap, с небольшой добавкой какой-нибудь LRU логики по очистке.
Обычно количество готовых библиотек под любую задачу никак не меньше, чем количество колес различных типоразмеров на авторынке.
А вот если действительно ничего подходящего при взвешенном рассмотрении не оказывается — тогда и вопроса нет, изобретать или не изобретать?
И, тем не менее, вдумчивое и глубокое изучение существующих инструментов — первый и обязательный шаг.
Я для своего велосипеда уже второй год не могу подходящую камеру купить. Пришлось купить чуть меньшего размера и перекачать её. Но едет не очень, особенно по камням плохо, и сдвигается внутри покрышки.
Тут есть 2 негативных момента:

1. Иногда на изучение и адаптацию готового решения уходит больше времени чем на написание собственного варианта.

2. Начинающим программистам крайне необходима практика самостоятельного написания различного рода решений, в противном случае они рискуют оставаться достаточно «посредственными» в своей профессии. По аналогии с тем, что хорошим писателем становится не тот кто читает больше книжек, а тот кто практикуется в их непосредственном написании.
Как мне кажется, начинающие программисты и так пишут код. По крайней мере я в свое время писал, и немало.
А вот с чтением этими новичками чужих хороших исходников дело обстоит не так радужно. В то время как если совмещать эту деятельность с написанием своего чудо-кода — результат получается гораздо лучше.

«Чукча не читатель — чукча писатель!»
Писать код с использованием имеющихся средств — это совсем не то же самое, что разрабатывать библиотеку «с нуля». Требуется другой уровень мышления, на пару порядков продвинутей, т.к. нужно учесть все возможные частные случаи и каким-то более-менее адекватным образом на них реагировать.
Так что обучение при написании подобных решений происходит в несколько раз быстрее, чем при написании обычного application-кода.
Как-то вы лихо поставили знак равенства между «другим уровнем мышления» и «начинающим программистом».
Весь мой опыт говорит — новичкам не до создания библиотечного кода, им бы хоть научится его читать да использовать.
Это потом, с годами опыта, возможно придет тот самый «продвинутый на пару порядков уровень».
А в самом начале не следует мучить неокрепший разум неподъёмными проблемами.
Заметьте, я не использоьвал понятие «начинающий программист». Я говорил об обучении, а оно нужно отнюдь не только начинающим, Вы согласны?
Нужно не столько обучение, сколько самообучение.
Компании программистов не учат — они деньги зарабатывают.
К тому же мне показалось, что если вы отвечаете на запись, явно говорящую о «начинающих» (равно как и предыдущая) и не уточняете отдельно предмет разговора — то именно о новичках и говорим.
А в целом — верно.
Зато ошибок при таком процессе «обучения» — лопатой копай. И это влияет на качество и сроки поставки конечного продукта, между прочим.
Подразумевается, что процессом обучения в данном случае должен руководить более опытный разработчик.
Хорошим писателем становится тот и только тот, у кого есть талант.
Если он много читает, то во-первых расширяет свой арсенал изобразительных средств, во-вторых будет знать, что его новый и оригинальный сюжет был изрядно заезжен ещё во времена Шекспира. С другой стороны, возможно, убережётся от расхожих штампов и создаст свой неповторимый набор.
Читать чужой код не менее полезно, чем писать собственный — там можно найти много интересных приёмов и, наоборот, примеров того, как делать не надо. Причём в программировании чужие штампы злом не являются*. Конечно, всё должно быть в меру — только читая чужой код программистом не станешь, но если только писать код, очень много сил и времени потратишь на поиск решения задач, которые уже давно решены, причём оптимальным образом. Кроме того, часто бывает полезно почитать чужой код, чтобы понять, как работает та или иная функция в библиотеке и как её лучше перегрузить (в терминах C++).

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

image
По-моему, упустили важный плюс своей библиотеки: её можно развивать именно в том направлении, которое нужно вам.
Спасибо, проапдейтил суммари топика.
«Не свою» тоже можно, никто не мешает.
Хорошо, если получается делать «по нормальному», с принятием патчей и совершенствованием оригинального продукта.
Иногда это сильно накладно: консервативная политика автора или (чаще) неумение вписаться в используемый процесс.
Что ж — сделайте fork. Всяко лучше, чем писать с нуля!
Бывают и закрытые библиотеки.
Бывают. С ними терзаний меньше — развивать такие не получится.
К вопросу о закрытых — иногда заказчик требует свою реализацию, которую можно закрыть.
Что ж — сделайте fork. Всяко лучше, чем писать с нуля!

Не всегда. Лучше всего, когда возможность развития закладывается в самом начале, поэтому может оказаться, что на определённом этапе всё равно потребуется переписывать, т.к. вам больше не подходят базовые принципы этой библиотеки, а вы уже потратили кучу времени на свой fork, и ваш конечный продукт тройным морским узлом на него завязан. В результате вы загоните в тупик и fork и продукт.
Не поймите меня неверно — я не сторонник идеи всё делать самому и почти всегда стараюсь найти готовое решение. Для создания своей библиотеки я вижу только две причины:
— то, что мне нужно, быстрее сделать, чем найти готовое и
— есть план развития, несовместимый с существующими библиотеками.
Но в обоих случаях необходимо соблюдать баланс.
Насчет «никто не мешает развивать не свою» — недавно на хабре была хорошая статья про бодание уже более полугода насчет отмены новшеств в функции memcpy из glibc.
Можно конечно сделать свою ветку существующей библиотеки, но тогда надо обязательно поставлять ее со своими разработками. А если у клиента уже стоит и используется такая библиотека из родной ветки — как быть? Ведь есть риск больших переделок под себя. А дорабатывать официальными путями — может оказаться слишком долго для вас и вашего проекта.
Я обычно отвечаю на три вопроса, прежде чем выбрать единственно правильный путь:
1. Является ли функционал библиотеки центральной частью разрабатываемой сиситемы? Если — да, то необходимо систему строить вокруг библиотеки, т.е. принять соглашение о кодировании, стиле и технологиях, которые используются в библиотеке и т.д. Если — нет, то предпочитаю написать своё, пусть и менее универсальное.
2. Является ли функционал библиотеки общим, т.е стандартные алгоритмы, структуры данных и пр.? Если — да, то использовать библиотеку.
3. Оцениваю баланс между порогом вхождения для использования библиотеки и реальную потребность в функционале библиотеки, т.е. если мне нужен из библиотеки ничтожный функционал, но при этом необходимо изучить всю инфраструктуру, то предпочитаю своё решение.
А вообще, опенсорс библиотеки удобно использовать как базу для написания своего решения. Всё же я сторонник разумного велосипедостроения.
Статья была бы шикарной, если бы по каждому пункту были бы примеры реальных задач, библиотек и т.д. То есть поменьше рассуждений, побольше дела.
Иногда нужно уметь оперировать абстракциями без примеров. Потому как составление адекватных примеров часто является в несколько раз более сложной задачей, чем реализация решения.
Люто-бешено фалломорфирую едва только заслышу что-то отдаленно напоминающее «нужно всегда использовать готовые решения! колёса! велосипеды!» или «я разработал xxx на yyy которому нет аналогов! сочни! вкусни!» — обе позиции одинаково ущербны, работа программиста — думать вумной головой вумные думки, принимать на их основе соот-щие решения, а не вдолбить в себе голову мантру и потом всем ее твердить. Когда-то оправдано использовать готовую библиотеку, в основном это оправдано там где область или глубоко специфична, или слишком всеобъемлюща, иногда оправдано разработать что-либо с нуля, в основном там где это неспецифичный функционал в котором ценна его однообразность с остальной кодовой базой.
В идеале при грамотном проектировании вопроса «готовая/самописная библиотека» возникать не должно вообще, так как на любой пшик должен быть описан свой интерфейс, и какая библиотека будет его реализовывать — не принципиально.
>В идеале при грамотном проектировании вопроса «готовая/самописная библиотека» возникать не должно вообще, так как на любой пшик должен быть описан свой интерфейс, и какая библиотека будет его реализовывать — не принципиально.

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

Если платная библиотека не позволяет сделать что-то важное для конечного приложения, и разработчики обещают добавить эту возможность в одной из следующих версий, то все равно лучше посмотреть на альтернативные решения. Довольно часто разработчики библиотеки сильно заняты и требуемый функционал может не появиться в ближайшие месяцы, а то и годы.
Опираясь на такие идеи, нужно сразу начинать с создания своей ОС, а то западло программировать в неизвестной операционной системе…
По поводу плюсов и минусов:
Касаемо «новых людей в команде» — скажу честно — что многие (90%) новички в проектах не знают, как работают готовые решения — поскольку проекты разнородные, и либы используются разные (если речь конечно не GNU LibC и других стандартных вещах)

Касаемо «патчинга» — если вовремя вносить изменения в код, то все будет хорошо. Большинство либ имеют типизированный набор интерфейсов, которые меняются только при переходе на новую версию (major) и как правило, остается поддержа (обратная совместимость) с ранними версиями (хоть и deprecated — но все равно имеет место быть).

Вообщем Я за совменщение обоих подходом, описанных автором. Ведь порой не нужно изобретать велосипед, достаточно его немного переделать и упростить/усложнить в зависимоти от нужд проекта.
Я бы еще добавил один момент по поводу поддержки решения:
Библиотека:
+ Поддерживается командной разработчиков (правятся баги, выходят новые апдейты, расширяется функционал).

Собственное решение:
— Необходимость в дополнительных ресурсах для поддержки разработки (поиск и исправление багов, рефакторинг, и т.п.).
Мои тезисы:
1) велосипеды — это добро
2) готовые решения — это добро

Как выбирать, мой алгоритм:
1) готовое решение решает ваши задачи, устраивает вас по интерфейсу, количеству дополнительного балласта, скорости и ресурсоемкости, и не оскорбляет ваши религиозные чувства? Берите, чо.
2) готовые решения есть, устраивают функционально, но не устраивают по интерфейсу? Напишите обертку и не мучайте свой мозг. Часто хорошие вещи специально готовят таким образом, чтобы их можно было заворачивать в свои обертки по вкусу.
3) готовые решения есть, но подходят не до конца (слишком мощные/слишком универсальные/чего-то не хватает) — подумайте, готовы ли Вы взяться за велосипед? Это может быть достаточно серьезной задачей. Скажем, речь идет о парсинге http-запросов. С одной стороны, все просто и можно сделать на коленке, через это все проходили. Немного угаснет энтузиазм при воспоминании про обработку multipart-форм. Потом вспомним про чанки. Потом про остальные «мелочи» типа кип-элив. И вот у нас получается точно такой же монстр, только непродуманный по архитектуре. Вы действительно понимаете на что идете? Если нет — берите готовое решение.
4) если готовы писать свой велосипед — опишите сразу, для себя, чем этот велос принципиально отличается от других. Он может экономить вам ценную память или быть на 10% быстрее. Он может быть оптимизирован под какие-то конкретные случаи. Он может быть похожим на некоторые другие, но будет обладать какой-то специфической концепцией. Опишите, ДЛЯ ЧЕГО вы его делаете. Покажите остальным, чтобы поправили и дополнили. Теперь — можно писать код :)

Если вы дошли до шага №4 — вы имеете шанс сделать библиотеку, про которую либо не будут спрашивать «зачем вы тратили на нее свои силы», либо у вас будет готовый ответ на этот вопрос (удобно сразу показывать новым членам команды). И библиотека гарантированно получится именно такой, какой вы ее описали изначально. В общем, повышаются шансы на то, что ваш велосипед тоже станет для кого-то стандартным решением — если его выложат в открытый доступ, например :)
На мой взгляд, попытка ответить на поставленный вопрос перечислением плюсов/минусов в корне неверна, т.к. плюсы легко оборачиваются минусами и наоборот в зависимости от текущей ситуации:
+ Быстрая разработка
Скорее, быстрое прототипирование. А в длительной перспективе борьба работа с неявной, сложной, медленной и глючной библиотекой может обойтись очень дорого.
+ Код оттестированный огромным количеством пользователей
Это заблуждение из той же серии, что «open source код безопасный, т.к. его постоянно просматривает множество людей». Пользователей этих зачастую не так и много, и ходят они обычно одними и теми же путями. И любая попытка использования библиотеки мало-мальски нетипичным образом приводит на нехоженные минные поля. Фактически, это утверждение верно только для базовых, основных библиотек, которыми пользуются действительно практически все.
+ Люди приходящие в команду знают как он работает
Очередная иллюзия. Вы тоже думали, что знаете, как оно работает… Кроме того это снова касается только основных библиотек.
+ Решает проблемы, которые вы возможно не предвидели бы, реализую библиотеку самостоятельно
Это правда. Особенно это критично в специфических областях, в которых лично Вы не разбираетесь — вроде криптографии. Но и здесь есть нюанс — эти проблемы могут никогда не коснуться вашего приложения, а библиотечные решения этих (для вас) несуществующих проблем могут сильно усложнить/замедлить код библиотеки (а в сложном коде больше багов, кстати — которые как раз вполне могут вас коснуться).
+ Программист концентрируется на функционале, а не на вспомогательной библиотеке
При прототипировании — да. А в реальном приложении зачастую приходится детально изучать используемые библиотеки чтобы найти причину возникших проблем, и времени на это может уходить очень много.
— Очень много классов, довольно сложная общая архитектура, поэтому тяжело разбираться в возникающих ошибках
Библиотеки бывают разные. Для меня как раз один из основных критериев при решении использовать ли чужую библиотеку (и даже программу) — простота и ясность её реализации. Кроме того, если задача решаемая библиотекой действительно сложна, то ещё не факт, что ваша собственная реализация будет лучше и проще, и что на её написание и отладку уйдёт меньше времени и сил чем на обнаружение и исправление ошибок в чужой библиотеке… кроме того, нередко удаётся эту работу переложить на автора библиотеки или сообщество её поддерживающее.
— Возможно не делает какую-то очень специфичную штуку, которая была бы вам очень полезна для вашей конкретной задачи
Нередко это знак, говорящий о том, что Вы смотрите не в ту сторону, и Вам эта штука тоже не нужна. И дописать одну специфичную штуку (поверх, или внутри библиотеки) обычно проще, чем переписать все нужные вам фичи этой библиотеки только ради того, чтобы добавить к ним одну специфичную более удобным способом (в своём, а не чужом коде).
— Не может решить вашу конкретную задачу самым оптимальным способом, так как внутри содержит кучу оберток и флагов для других задач
Звучит как premature optimization, which is the root of all evil. :) И, чаще всего, именно этим и является. Так что это не является минусом до тех пор, пока профайлинг не докажет обратное.
— При самостоятельно патчинге библиотеки могут возникнуть проблемы с будущим обновлением версии
Ну, есть «проблемы» и «ПРОБЛЕМЫ». Обычно проблемы поддержки своих патчей несущественны по сравнению со сложностью переписывания библиотеки.
+ Члены команды знают как все работает в деталях
Тоже заблуждение, выше в комментариях об этом уже сказали.
+ Легко определятся причина ошибки, так как написанный код минимален
Чаще всего да, но вообще-то это сильно зависит от качества этого кода.
+ Максимально производительное решение
Снова premature optimization.
+ Возможность развития библиотеки в нужном вам направлении
Надо полагать, все существующие библиотеки развиваются в других направлениях, раз возник такой фактор. Что-ж, это либо означает что Вы что-то упускаете из виду и Вам туда тоже не надо, либо NIH-синдром, либо у Вас действительно специфичная задача и существующие библиотеки Вам не подходят — но тогда вопрос выбора чужой библиотеки просто не стоит за отсутствием подходящих вариантов.
— Требуется высококвалифицированный разработчик для написания хорошей библиотеки
Это не минус, это требование. Если такого специалиста нет, то вопрос писать или не писать свою библиотеку просто не стоит. А если он есть, то это данность, а не плюс или минус.
— Длительная разработка
Как я уже упоминал выше, в длительной перспективе разработка своей библиотеки может оказаться дешевле по ресурсам (включая время) чем борьба с чужой библиотекой. Так что это однозначный минус только для прототипирования.
— Содержит достаточное количество ошибок, особенно на стадии внедрения
Зависит от квалификации разработчика и сложности задачи. Зачастую своё решение содержит только необходимый лично Вам функционал, и за счёт этого во много раз проще универсальной библиотеки, а значит и содержит во много раз меньше ошибок.
— Новые люди в команде не знают как оно работает
Тоже упоминалось выше. Фактически, чем сложнее система, тем меньше Вы знаете как она работает. В этом смысле своё простое частное решение обычно намного предпочтительнее чужого сложного универсального.



Я бы сформулировал ответ на заданный в топике вопрос так:

— НЕ ПИСАТЬ, если Вы не обладаете необходимой квалификацией (как программист или в конкретно этой области) для качественной реализации этой библиотеки;
— НЕ ПИСАТЬ, если речь идёт об одной из стандартных, базовых библиотек, которые используются практически всеми;
— НЕ ПИСАТЬ, если Вы разрабатываете прототип, и не опасаетесь что начальство/заказчик захочет выставить его в продакшн;
— НЕ ПИСАТЬ, если существующая библиотека написана достаточно просто и ясно;
— НЕ ПИСАТЬ, если Вы не уверены, что Ваше решение будет значительно проще;
— в остальных случаях разработка своей библиотеки может иметь смысл, особенно если Вы сможете удержаться от написания очередного сложного и раздутого универсального решения, ограничившись минимально необходимым Вашему проекту функционалом.
выбираю по следующим критериям:
— если надо сделать какую то мелкую фигнюльку, которая есть в megaframework (или почти есть) — лучше сделать её самому, а не грузить тонны кода ради мелочевки
— если надо сделать быстро — берем megaframework, который максимально устраивает и меняем функционал в ТЗ (ищем компромиссы), чтобы идеально подошло для megaframework
— если есть куча времени и проект должен быть например мелким по объему и шустро работать — лучше писать своё под этот конкретный проект

но наверное все руководствуются оптимальным соотношением гемора/качества/скорости/etc… всё зависит от проекта

по поводу платный и закрытых вещей — то и дело вылезает что какого то функционала нет и приходится из того что есть собирать то что надо — как итог получаем не совсем то что надо за время которое можно было бы потратить на свой велосипед которые идеально решает поставленную задачу… а самая печалька наступает когда разработчики закрытой штуки завяляет о том что не собирались и не будут делать то что надо — и снова возвращаемся к своим велосипедам из костылей и непонятной формы колес =)
можно не читать — полностью согласен с человеком выше =)
Серебрянных пуль нет. Думать головой и выбирать нужно в каждом отдельном случае.
Стеклянный, оловянный, деревянный!

Никаких «кожанных» и «серебрянных».
Хватает библиотечной скорости — используйте библиотеку. Естественно, безопасность должна быть проверена.
Из практики очень часто бывает так, что готовое решение содержит кучу багов или сделано всё через ж… И получается что вместо концентрации на функционале, мы боремся с недостатками либы.
Плюс к этому выбор нужной либы тоже является своего рода рулеткой — и то что либо опен соурс еще не далеко не значит что там всё нормально…
А еще бывает так, что при начальном подключении чужой библиотеки всё вроде бы хорошо, а с годами вылазят проблемы — то в очередной версии либы не выдержат обратную совместимость, то применят решение, которое резко снижает производительность именно в вашем варианте её использования, или не поддерживает новых требований стандартов (по этой теме), то еще какой-нибудь неприятный сюрприз (также как и при смене версий ОС :).

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

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

Или недавно была задача написать парсер (java) тут выпендриваться я не стал и заюзал HtmlParser, реализовав лишь пару недостающих фильтров. Но вот если бы эта библиотека не имела интерфейсов для фильтров — было бы туго.

Итог — все зависит от конкретно задачи и конкретно библиотеки.
На мой взгляд понятие «существующей библиотеки» достаточно размыто, чтобы быть равноценной группой с собственным велосипедом. А потому мой ответ на вопрос топика — смотреть по ситуации.
И тут (помимо вещей, которые уже были затронуты в комментариях выше) важен вопрос собственно библиотеки. Я не раз натыкался на подобную ситуацию, когда изначально ожидаешь описанных в топике плюсов от библиотеки, а при ее детальном рассмотрении понимаешь, что это скорее ближе к чужому велосипеду (со всеми минусами от велосипеда).
Ну, т.е. ладно, если у библиотеки какой-то глобальный разработчик (крупная компания / спецы и т.п.). А если хз кто? А потом вылазит, что вообще не понимаешь, как это у него работало (хотя, возможно, это минус тебе самому ^_^). А когда начинаешь править (благо, если попался опенсорс) — оказывается документации 0, комментирование слабое. И встаешь.
Мораль сей басни: библиотека библиотеке рознь.
Сталкивались ли вы когда-нибудь с проблемой выбора: использовать float, double или int? Я никогда не понимал этого вопроса и всегда отдавал предпочтение double.
Выбор между целочисленным типом и типом с плавающей точки зависит от природы данных, и никогда не делается «с потолка». По-крайней мере профессионалом.
А вот выбор между float и double… float имеет смысл использовать только в том случае, если имеется большой объем данных, которые влезают в этот тип, причем их нужно только передавать, без проведения каких-либо вычислительных операций. Если же есть арифметика — однозначно double, т.к. большинство стандартных функций все равно преобразует в double.
Есть ещё одна проблема с float и арифметикой. Если используется умножение или деление то погрешность накапливается слишком быстро.
UFO just landed and posted this here
Для существующей библиотеки есть минус в его открытости: например, если злоумышленник хочет вскрыть некий сайт, то ему значительно проще сделать это, имея исходный код его частей. В т.ч. облегчается написание ботов, которые могут анализировать сайты на наличие той или иной версии какого-либо движка и в автоматическом режиме использовать известную уязвимость.

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

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

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

В общем, так можно продолжать до бесконечности, приводя доводы и в ту и в другую сторону, но в конечном счете, на мой взгляд, все сводится к индивидуальной ситуации с огромным количеством самых разных факторов.
От себя добавлю, со стороны своего опыта:
> + Члены команды знают как все работает в деталях (пока не уйдут из команды)
Наблюдал как-то как неделями отлаживали неработающую логику в библиотеке, которая TCP соединение держала. Диаграмма состояний одного только «disconnect'a» состояла из примерно трех десятков переходов. Да, сам автор ею занимался, так все остальные предпочитали держаться от этого кошмара подальше.

> + Легко определятся причина ошибки, так как написанный код минимален
> + Максимально производительное решение
Да откуда это следует? Код зачастую пишут как challenge, чтобы «изучить ещё одну технологию». В результате — полное незнание стандартных грабель в данной области, код обрастает костылями. Производительность? А как вам щедро разбросанные по коду «sleep(xxx);» с аргументацией, что «без них оно почему-то нестабильно работает»?
«Кадры решают все».

Если у вас нету достаточно квалифицированных кадров, то извиняюсь, нефиг выпендриваться, а брать по максимуму готовое.
«In theory, theory and practice are the same. In practice, they are not.»

В идеальном мире, согласен, пусть программисты сами все компоненты пишут. В реальном — я бы 10 раз подумал, прежде чем очередной велосипед городить.
Не могу согласиться :)

Как в идеальном, так и реальном мире следует использовать тот подход, который наиболее соответсвует ситуации, это может быть и готовое решение, а может и свое. Нельзя категорично заявлять «чужое луше» или «свое лучше». Но как тут выше уже правильно написали — если у вас нету достаточно сильных кадров, то выюирать не приходится — только свое.
>если у вас нету достаточно сильных кадров, то выюирать не приходится — только свое.
Вы не ошиблись? Если уровень программиста не высок, то его «велосипед» — это не велосипед, а мина замедленного действия.

Пусть он (для примера) нити из boost'а возмёт, а logger — ещё из какой-нибудь распространённой библиотеки, чем «своё, родное» писать будет.
Опечатка по Фрейду ) Да, конечно имел в виду, что для новичков только готовые решения.
В обоих случаях есть плюсы и минусы.
Хотя из-за лени разбираться в чем либо мне приходится писать все с нуля, т.е, хотя вот jquery я освоил, и это действительно замечательный фреймворк, еще бы ручки(крючки) дошли до YII, было бы вообще супер, хотя бы потому что, не придется писать херову тучу функций для выводов и авторизации, ибо в гугл идти лень…
UFO just landed and posted this here
Как правила для готовых решений уже есть какая-то документация, описания, можно найти форумы по данной тематике, где люди описывают те или иные решения.

А вот собственные решения, хорошо, если подробными комментариями в коде снабжены (а не комментами вида: «ептель, не знаю как, но заработало. Не трогать!»)

Так же, могу сказать, что разбираться в «собственной» разработке фирмы, которую разрабатывали поэтапно разные люди в разное время среднего уровня (хорошие программисты, но не гуру, которые знают все и вся) — это мрак и ужас.
Во первых, каждый привносил что-то свое, свои принципы, правила, виды… Зачастую это все идет в разрез с общепринятыми правилами и нормами.
Во вторых, только реально гуру порой могут учесть все возможные нюансы, особенности и т. п. Зачастую в некоторых случаях приложении отказывается работать (при переносе на другую, почти такую же платформу). А все потому, что есть некоторая особенность, о которой знают далеко не многие. В библиотеке, возможно, этот нюанс найдут и пофиксят. А вот в собственной разработке такие баги могут быть не замечены годами и в какой-то момент они вылезут, причем могут наложится одна на другую.
И в такой момент уже «десятый» программист, которые работает с такой самописной библиотекой разводит руками и руководству ответственно заявляет: «на устранение этой ошибку может понадобится до полугода». (утрирую, но все зависит от сложности собственной разработки и «кривости» ее кода, отсутствия комментариев по коду и документации).
Нет универсального решения — да или нет. Делать выбор нужно исходя из конкретной ситуации.

Пару раз ошибившись наберёте достаточно опыта. Главное не лениться анализировать своих решения.
К минусам библиотек еще стоит добавить, что так же тысячи хакеров изучают и постоянно находят новые уязвимости.

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

Реальный пример из нашего проекта — logging, сначала использовали Enterprise Library, сейчас абсолютно безболезненно будем переходить на log4net. То же самое с кешированием.
По-моему не учтены основные минусы библиотек:
— время на осваивание новой библиотеки сравнимо с разработкой требуемого функционала
— использование стороннего кода делает проект зависимым от стороннего разработчика
— разные члены команды могут использовать разные библиотеки, функционалы которых часто перекрываются, либо вообще повторяют друг друга
Вы не забумывались, что написав класс-оболочку вокруг библиотеки, вы избавитесь от всех ее «недостатков»?
В том числе и от наличия документации к библиотеке — для враппера надо будет свою документацию писать.
Почему-то никто не вспомнил, что готовое решение нужна сначала найти (или потратить кучу времени, чтобы убедиться, что его нет), потом проанализировать на пригодность использования для проекта, изучить интерфейсы, оценить затраты на интеграцию и т. п. Плюс во многих случаях находится не одно готовое решение, а несколько, причём без явного лидера, и в идеале нужно проанализировать их все и выбрать единственное «своё», а не монетку бросать.

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

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

Вопрос где этот минус «жирнее» — т.е. тут вопрос не холивар «быть или не быть», а вопрос Оценки Рисков.

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

Риски своего решения:
Комманда разработчиков может реально и не потянуть написание своей библиотеки в разумные сроки. Заточенная под свои нужды (а если она не заточенна, то и смысла в ней нет) библиотека в наиболее своей важной части-идеологии обычно завязанна на дефицитный ресурсвремя и внимание Ведущего Разработчика (! да именно так, с большой буквы!). А если ведущий разработчик сильно занят другими делами, как это обычно и бывает… правильно, имеем результат-затягивание как время запуска проекта так и стопор всего проекта. Ведь без четкой вменяемой методологии любые попытки писать что-то свое априори обречены.

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

Есть два вида проектов (имею ввиду коммерческую разработку, а не программы-хобби и не учебные примеры) и два соотвествующих подхода к их разработке:
1) Програмный продукт по принципу склепал-впарил заказчику, а дальше что с ним делать это уже геморой заказчика, мы сдали и умыли руки, у нас на очереди еще сотня таких на сегодня.
2) Наш проект не заканчивается, мы ведем проект. Это либо наш внутренний проект, либо проект где мы занимаемся внедрением, поддержкой и консультациями.

Каждый из этих подходов имеет свои ключевые факторы и риски влияющие на сам процесс разработки:

В первом подходе к проекту ключевой фактор: Минимизация времени и стоимости начальной разработки (потому как другой нет, долговременная поддержка не предусматривается). Проект на выходе — нечто чуть большее чем стандартное «hello world», наспех сляпанное из непонятного клубка первых попавшихся библиотек и фреймворков. Да, естественно, руками самых дешевых программистов (тех кого неполиткорректно называют индусскими быдлокодерами) Ведь держать в штате дорогих, опытных программистов — непозволительная роскошь, да и ввиду того что они «слишком много думают» механистичекую генерацию кода они выполняют слишком медленно. Всяких тестировщиков и пр. само собой тоже нет, ибо дорого, и будет мешать быстро сделать-впарить.
Основной риск при этого первом подходе: Заказчик попадется опытный, прошаренный и въедливый, он может устроить тчательное тестирование, и быстро поняв, что не требования ни функционал не реализованы и не будут, ловить нечего, и уйти, хлопнув дверью.
Впрочем риск легко компенсируется демпинговой ценовой политикой — подумаешь, пара клиентов «хлопнули дверью»-с такими ценами у нас этих клиентов сотня.
(Я не хочу сказать что такое подход это «хорошо/плохо» это просто имеет место и имеет право на жизнь.)

При втором подходе ключевой фактор: Сразу затачиваемся на длительную жизнь проекта. С запуском проекта, он не заканчивается, а только начинается. Т.е. на выходе после процесса начальной разработки и тестирования имеем конкурентоспособный (иначе смысла нет) продукт, ориентированный на прибыль в долгосрочной перспективе (опять же, иначе смысла нет). Любое удачное нестандартное решение — это «фишка проекта», его потенциал, его сила, конкурентное преимущество. Проект уже на этапе разработки проектируется готовым к прохождениям «кризисов роста», к будущему расширению и рефакторингу. Производиться тчательное тестирование с пристрастием для каждого как своего решения так и стороннего. Чем опытнее разработчики и чем они думают дальновиднее — тем лучше. Естественно опытные разработчики — это дорого, реально дорого.
Риск второго подхода один: Возможна чрезмерная стоимость проекта (в принципе сам второй подход уже как бы предполагает высокобюджетность). Заказчик/инвестор/совет директоров может испугаться сумм, где знаков как в мобильном телефоне. Кстати, из-за этого риска в кризис закрылось очень много перспективных проектов.
Этот риск компенсируется тем, что по сути даже один такой проект, будучи успешным способен кормить фирму (и не одну). Плюс-минус полгода, плюс-минус миллион на разработку — это влияет только на срок окупаемости затрат на проект, причем связь нелинейная.

А теперь, если мы снова вернемся к нашей теме («свое»/«сущенствующие решения»), и посмотрим на эти два вида проектов, делаем вывод для каких проектов в пользу какого решения склониться :)

Sign up to leave a comment.

Articles