Boroda aka Hamster (fantaseour) wrote,
Boroda aka Hamster
fantaseour

Categories:
  • Mood:
  • Music:

Про изобретение велосипеда и Not-Invented-Here Syndrome

Поговорим об изобретении велосипеда (оно же по-английски reinventing the wheel).

Многие менеджеры, при поиске подрядчиков, где-нибудь в ru_freelance говорят — возьмите это, это и это — и скрестите, работы там на 20 минут, типа все изобретатели велосипедов идут лесом. (Особо выраженные экземпляры добавят к этому еще "пионерам просьба не беспокоить, камменты скринятся, аттачменты режем"). Все ведь знают, что только прыщавые пионеры изобретают и пишут "с нуля". "Хочешь завалить проект — начни писать с нуля", — так? Не так. Даже совсем не так.

Time for a pop quiz.
1. Code Reuse is:
a) Good
b) Bad
2. Reinventing the Wheel is:
a) Good
b) Bad
3. The Not-Invented-Here Syndrome is:
a) Good
b) Bad

Of course, everybody knows that you should always leverage other people's work. The correct answers are, of course, 1(a) 2(b) 3(b).
Right?
Not so fast, there!

In Defense of Not-Invented-Here Syndrome, by Joel Spolsky

Особенно опасна тенденция изгнания всех доказательств из школьного обучения. Роль доказательств в математике подобна роли орфографии и даже каллиграфии в поэзии.

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

Newbie is bright and energetic. He figures his best chance of succeeding is to learn to use the tools and libraries that have been handed to him as intelligently as possible. He limbers up his typing fingers, hurls himself at the challenge...and enters hell.

Everything takes longer and is more painful than he expects. Beneath the surface gloss of their demo applications, the components he is re-using seem to have edge cases in which they behave unpredictably or destructively — edge cases his code tickles daily. He often finds himself wondering what the library programmers were thinking. He can't tell, because the components are inadequately documented…

The Tale of J. Random Newbie,
The Art of Unix Programming

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

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

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

Позволю себе привести еще одну цитату про написание фреймворков и библиотек. Она принадлежит Маркусу Бэйкеру (оригинал):
Вот совет, как писать гибкий и реюзабельный код:

1) Напиши приложение.
2) Напиши еще одно приложение.
3) Выдели общие места и используй их, как базис для следующего приложения.
4) Повтори.

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

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

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

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

2. Следует отличать библиотеки от фреймворков.

Фрэймворк, — это набор взаимодействующих классов, который организует воспроизводимую (reusable) архитектуру, необходимую для создания некоторого класса приложений. Например разного рода графические редакторы: для рисования, для рисования нот или для черчения. Также фреймворк может предоставлять набор инструментов для написание компиляторов под разные платформы. Как вариант — фреймворк для написания разного рода финансовых инструментов. Программист адаптирует фреймворк под конкретную задачу, например наследуя абстрактные классы.

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

Design Patterns Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

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

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

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

Фреймворк, это как рубашка, которая ближе к телу. Это то в чем разработчик может что-то менять, рефакторить, использовать. Поэтому фреймоворк у каждого свой. Опять же правильно смотреть что делается у соседа — можно взять идеи и реализации — это как раз плюс опенсорца.

А вот как раз компоненты, — то куда разработчик скорее всего не полезет — очень даже можно брать готовые - форум, adodb, phpmailer, zip-gzip из phpmyadmin.

Библиотеки вставлять в свое приложение значительно проще, т.к. используется довольно изолированный от остального мира API.

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

Взял из стандартного репозитория PEAR библиотеку Console::Getopt и сразу споткнулся о две вещи.

1. PEAR имеет свой обработчик ошибок, который перехватывает стандартные вызовы. У меня тоже аналогичный обработчик используется. Сразу вопрос о конфликте :)
2. Формат в котором библиотека выдает результат — обычный массив, а использовать удобно ассоциативный.

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

3. Еще один момент — иногда пока поймешь, как библиотека работает — сам напишешь что-то похожее — это как с теоремами в матанализе — надо знать не только теорему, но и ее доказательство (см. цитату акад. Арнодьда в выноске). Нет смысла брать суровый MVC фреймворк, если ты не знаешь, как этот MVC работает; если ты не знаешь как работают паттерны, — ты не сможешь использовать библиотеку, которая предоставляет соответствующий интерфейс. Пока ты занимаешься изучением этого вопроса, скорее всего у тебя уже родится небольшая наработка на заданную тему.

4. В статье Спольски In Defense of Not-Invented-Here Syndrome говорится про то, что если ты разрабатываешь что-то, где существенную роль играет определенный класс библиотек или фреймворк, то есть смысл иметь свой собственный в этом месте, — чтобы иметь конкурентное преимущество в оперативных изменениях. Как пример — игры и 3-d движки. У лидеров у каждого свой движок.

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

6. Вообще, изобретая велосипед, мы изобретаем лучший велосипед, и это совсем не плохо! Иначе бы вместо автомобилей так на велосипедах бы и ездили.

Вообще мир устроен так, чтобы практически во всем (ну кроме другого глобуса) было разнообразие. Если не изобретать велосипедов, жить станет скучно!

Tags: development
Subscribe
  • Post a new comment

    Error

    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 7 comments