А компетентен ли советчик? Проблемы рекомендации «не изобретай велосипед»

в 18:52, , рубрики: code review, как не надо делать, коммуникации, образование, Социальные сети и сообщества, эффективное общение

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

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

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

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

Рассмотрим несколько случаев.

image
Источник

API над API

Один из распространенных случаев обвинения в велосипедостроительстве — самостоятельное написание обертки API какого-то сервиса, реализации которого уже имеются.

Случай из моей практики.

Необходимо было реализовать загрузку данных из Facebook в наш сервис. Язык мейнстримовый и библиотека от самого Facebook нагуглилась за 2 минуты.

Документация библиотеки несоответстововала текущему программному интерфейсу, вокруг каждой манипуляции накручивалось очень много лишних действий. Библиотека оказалась очень низкого качества.

Результат: через 1.5 часа работы с ней, не удалось даже авторизоваться.

Коллега реализовал собственную обертку web-api фейсбука. Суммарно, на создание обертки и связанной функциональности на стороне сервиса у него ушло около часа. На вопрос "а зачем ты тут навелосипедил", он отвечал следующие несколько дней.

Подобное особенно ярко проявляется в мейнстримовых язык с большим коммьюнити: появляется нездоровая тенденция публиковать обертки API над другим API, под лозунгами "For humans" и "In simple way". Такие обертки устаревают, как только оборачиваемый интерфейс обновляется, а авторы забрасывают такие "проекты", делая код, их использующий, нерабочим.

Здравый вопрос: и что, каждый раз писать такие обертки вручную?

Ответ: Куда более сильным решением для больших оберток будет использование кодогенератора, интерпретирующего спецификации.

Контроль над кодовой базой и отказ отвечать за чужие ошибки

В кругах wannabe разработки компьютерных игр такая фраза адресуется любому, кто посмеет реализовать свой движок. "Зачем изобретать велосипед? Возьми юнити!". Или Game Maker, или, не, дай бог, Defold.

Казалось бы, двиглоконструктор предоставляет все необходимые инструменты для разработки, Многие из них кроссплатформенные и вообще упрощают жизнь.

Как должен поменяться контекст здесь, чтобы появилась необходимость делать свой движок?
Как минимум, это контроль над кодовой базой и функциями движка (например, на ряде моделей контроллеров гейммейкер стабильно глючит, и поправить это бывает крайне проблематично). То есть необходимо снизить вероятность встретить "чужой баг", исправить который cамостоятельно либо невозможно, либо крайне затруднительно.

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

К тому же, нет необходимости увеличивать суммарный объем кодовой базы, если от движкаконструктора используется малая часть его функций, а необходимые инструменты все равно нужно дописывать самостоятельно, попутно контролируя корректность их работы с движком.

Например, исходя из подобных посылок Томми Рефенес написал свой движок для Super Meat Boy.

Кто-то возразит: "Но ведь в сторееще каком-то хранилище, есть же гора пресетовинструментоврасширений!".

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

Мнимая идентичность. Притягивание задачи за уши.

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

Хороший пример: CluNet.

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

Вывод

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

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

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

Или, по-капитански обобщая:

Прежде, чем решать — думай.
Прежде, чем говорить — думай.
И вообще — думай.

Автор: Роман Равилевич

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js