В этой статье я изучаю анатомию успешного проекта создания свободно распространяемой программы fetchmail, который реализовывался специально с целью проверить некоторые удивительные идеи относительно разработки програмного обеспечения, подсказанные всей историей создания операционной системы Linux. Я попытаюсь рассмотреть их с точки зрения анализа двух фундаментально различающихся стилей разработки. «Соборная» модель, проповедуемая большей частью мира коммерческого ПО, противопоставлена «базарной» модели мира Linux. Я покажу, что эти модели сформировались на основе диаметрально противоположных предположений о сути задачи отладки программ. Я готов, основываясь на опыте Linux, привести аргументы в пользу утверждения о том, что «чем больше глаз, тем незначительнее ошибки», предложить полезные аналогии на примере других самокорректирующихся систем самодеятельных агентов, и, в заключение, представить вниманию читателей некоторое исследование, касающееся перспектив подобного подхода для будущего программного обеспечения.
Собор и базар
Linux революционна. Кто мог всего лишь нсколько лет назад (в 1991 году) предположить, что операционная система мирового класса может, как по волшебству, объединить усилия нескольких тысяч разработчиков, живущих в самых разных уголках планеты и связанных только тонкими нитями Internet?
Определенно, не я. К тому моменту, как я впервые в начале 1993 года услышал о Linux, я уже около десяти лет занимался разработкой Unix и свободного программного обеспечения. Мне посчастливилось быть среди первых участников проекта GNU в середине 80-х. Я выпустил достаточно свободно распространяемых программ, разрабатывая или принимая участие в разработке нескольких программ (nethack, режимов VC и GUD для Emacs, xlife и других), которые широко применяются и сейчас. Я считал, что знаю, как это делается.
ОС Linux перевернула мое представление о том, что я считал известным. Я многие годы проповедовал базовые принципы разработки Unix: небольшие инструментальные средства, быстрое создание прототипов и эволюционное программирование. Но я также верил и в то, что существует определенный, критический уровень сложности, который требует более централизованного, априорного подхода. Я был уверен в том, что большую часть важного программного обеспечения (операционные системы и действительно большие инструментальные средства, такие как Emacs) должны создаваться как соборы, тщательно прорабатываться отдельными экспертами или небольшими группами мудрецов, работающих в величественной изоляции, причем до поры до времени никакие бета-версии выпускаться не должны.
Стиль разработки, предложенный Линусом Торвальдсом (выпускать как можно раньше и чаще; передавать все, что можно; быть доступным до неразборчивости), воспринимался как нечто удивительное. Никакой спокойной и благоговейной атмосферы строительства собора. Вместо этого сообщество Linux напоминало огромный говорливый восточный базар, с множеством разнообразных программ и подходов (который надлежащим образом символизировали узлы с архивами Linux, куда отправляли свои решения все, кто хотел), откуда логически связанная и стабильная система, казалось, могла возникнуть только благодаря чуду, да и то не одному.
Тот факт, что этот «базарный» стиль по всей видимости работает, причем работает очень хорошо, вызвал шок. Оглядываясь на прошлое, я понял, что упорно работал не только над конкретными проектами, но также и стремясь понять, почему мир Linux не только не был погребен в этом хаосе, но, казалось, становился все сильнее и сильнее, причем такими темпами, какие трудно представить для традиционных «строителей собора».
Думаю, что к середине 1996 года я постепенно начал это осознавать. Мне представился прекрасный случай проверить свою теорию — реализовать проект, связанный с разработкой свободного программного обеспечения, который я сознательно старался вести, придерживаясь «базарного» стиля. Так я и сделал, и успех превзошел все ожидания.
В данной статье я расскажу об этом проекте. Я хочу воспользоваться ею с тем, чтобы предложить ряд афоризмов, касающихся эффективной разработки свободного программного обеспечения. Далеко не все эти утверждения я впервые узнал, соприкоснувшись с миром Linux, но вы увидите, как мир Linux придал им особое значение. Если я прав, то они помогут вам понять, что именно позволило сообществу Linux стать столь богатым источником превосходных программ и, возможно, эти утверждения помогут вам работать более производительно.
Почта должна доставляться адресату
С 1993 года я занимался техническими вопросами в небольшой компании Chester County InterLink (CCIL), предлагавшей услуги доступа в Internet (я был одним из основателей CCIL и написал уникальное программное обеспечение для доски объявлений — вы можете ознакомиться с ним в сети telnet по адресу locke.ccil.org (telnet://locke.ccil.org/). Сейчас оно позволяет обслуживать около трех тысяч пользователей по тридцати каналам). Эта работа позволяла мне 24 часа в сутки обращаться к сети по каналу на
56 Кбит/с, используемом в CCIL — фактически, это было просто необходимо для выполнения моих служебных обязанностей!
Соответственно, мне приходилось постоянно работать с электронной почтой в Internet. По ряду причин оказалось, что заставить SLIP работать так, чтобы он мог передавать сообщения между моим домашним компьютером (snark.thyrsus.com) и CCIL, очень сложно. Когда, наконец, мне это удалось, выяснилось, что я должен периодически соединяться по telnet со своим сервером, чтобы проверить пришедшие сообщения. Я хотел всего-навсего, чтобы моя почта доставлялась на сервер так, чтобы я получал уведомление о ее появлении и мог обработать ее с помощью всех имеющихся у меня локальных инструментальных средств.
Простое перенаправление сообщений в sendmail не работало, поскольку моя личная машина не всегда была подключена к Сети и не имела статического IP-адреса. Мне требовалась программа, которая могла бы поддерживать связь через SLIP-соединение и отправлять мою почту так, чтобы она доставлялась локально. Я знал, что такие системы существуют, и что большинство из них используют простой прикладной протокол, называемый POP (Post Office Protocol). И, весьма вероятно, к тому времени уже существовал сервер POP3, поставлявшийся с операционной системой BSD/OS, которая была установлена и на сервере locke.
Итак, мне был необходим клиент POP3. Поэтому я отправился в Сеть и нашел его. На самом деле, я нашел целых три или четыре таких клиента. Некоторое время я работал с pop-perl, но в нем отсутствовало то, что казалось совершенно очевидным — возможность выяснить адреса полученной почты так, чтобы по ним можно было корректно послать ответы.
Проблема состояла в следующем. Предположим, что некто по имени «Джо» на сервере locke послал мне почту. Если я получил почту на сервере snark и затем попытался ответить на нее, мой почтовый модуль с готовностью попытался бы отправить ее несуществующему «Джо» на сервере snark. Редактирование вручную адресов с тем, чтобы добавить к нему «@ccil.org» довольно быстро выросло бы в серьезную проблему.
Безусловно, эту работу должен был выполнять компьютер. Но ни один из существующих POP-клиентов не знал, как это можно сделать! Отсюда следовал первый важный вывод:
- Каждая хорошая работа над программным обеспечением начинается с реализации персональных целей разработчика.
Возможно, это кажется достаточно очевидным (это давно вошло в пословицу «Голь на выдумки хитра»), но слишком часто разработчики программного обеспечения тратят дни на упорную работу над программами, которые им либо не нужны, либо не нравятся. Но только не в мире Linux, чем, возможно, и объясняется, почему качество программного обеспечения в сообществе Linux в среднем столь высоко.
Поэтому, должен ли я сразу кинуться в омут создания нового POP3-клиента для того, чтобы конкурировать с уже существующими? Никогда в жизни! Я тщательно проанализировал утилиты POP, которые уже были, спросив себя, какой из них более всего похож на клиента, который мне необходим? Поскольку.
- Хорошие программисты знают, что писать. Великие программисты знают, что следует переписать (и затем использовать вновь).
Хотя я отнюдь не считаю себя великим программистом, я попытался поставить себя на его место. Важная отличительная особенность великих программистов как раз и состоит в том, что они конструктивные лентяи. Они делают то, что делают не ради самого процесса, а ради результата и почти всегда проще начать, отталкиваясь от хорошего, частичного решения, чем вообще с нуля.
Линус Торвальдс (http://www.tuxedo.org/~esr/faqs/linus), к примеру, на самом деле и не пытался писать Linux с нуля. Вместо этого, он начал использовать тексты и идеи Minix — небольшой Unix-подобной операционной системы для клонов ПК. В конечном итоге весь текст Minix пришлось выбросить или полностью переписать, но пока он присутствовал в проекте, то служил своего рода «бегунками» для ребенка, которые в конце концов превратились в Linux.
Примерно в том же духе поступил и я, анализируя прекрасно написанную существующую утилиту POP, для того, чтобы использовать ее в качестве основы разработки.
Традиция использования исходных текстов в мире Unix всегда была ориентирована на повторное использование кодов (вот почему для проекта GNU в качестве базовой операционной системы была выбрана именно Unix, несмотря на серьезные оговорки относительно самой операционной системы). Мир Linux практически полностью реализовал технологический потенциал этой традиции; созданное в этих рамках свободно распространяемое программное обеспечение исчисляется терабайтами. Так что, если вы потратите какое-то время на поиск достаточно приемлемого первоначального варианта, в мире Linux скорее всего это принесет результат намного лучший, чем что-либо иное.
Так и произошло со мной. Вместе с тем, что я обнаружил ранее, и в результате второй попытки было выбрано девять кандидатов — fetchpop, PopTart, get-mail, gwpop, pimp, pop-perl, popc, popmail и upop. Сначала я остановился на утилите fetchpop, разработанной Сеунг-Хонг Охом. Я интегрировал в эту утилиту возможность генерации заголовка, а также внес ряд усовершенствований, которые были приняты ее автором в версии 1.9.
Несколько недель спустя, однако, я случайно натолкнулся на текст popclient, подготовленного Карлом Харрисом, и осознал свою ошибку. Хотя fetchpop отличался рядом оригинальных идей (таких, как режим демона), он мог обрабатывать только POP3 и был написан недостаточно профессионально (в тот момент Сеунг-Хонг был ярким, но неопытным программистом, что и проявилось в этой утилите). Текст Карла оказался лучшего качества, достаточно профессионально написанным и согласованным, но в его программе отсутствовал ряд важных и довольно сложных в реализации возможностей fetchpop (в том числе и те, которые я написал сам).
Дорабатывать fetchpop или начать сначала, отталкиваясь от popclient? Если выбрать второй вариант, то мне придется отказаться от работы, которую я уже проделал в обмен на более качественную основу для дальнейшего развития проекта.
Практическим стимулом все же решиться на использование popclient был тот факт, что последний поддерживал несколько протоколов. POP3 — наиболее популярный протокол для почтовых серверов, но далеко не единственный. Fetchpop и другие конкуренты не поддерживают POP2, RPOP или APOP, и у меня уже были общие соображения относительно возможного добавления IMAP (http://www.imap.org/) (Internet Message Access Protocol, недавно появившегося и самого мощного почтового протокола).
Но у меня была и чисто теоретическая причина подумать о переходе на popclient, опираясь на то, что я узнал задолго до Linux.
- «Если вы решили принести в жертву свою жизнь, вы сделаете это в любом случае». (Фред Брукс, «Мифический человеко-месяц», глава 11).
Или, говоря по-другому, зачастую вы на самом деле не можете понять суть проблемы до тех пор, пока в первый раз не попробуете ее решить. В следующий раз, возможно, вы будете знать уже достаточно для того, чтобы выбрать правильный путь. Так что если вы хотите понять задачу правильно, будьте готовы к тому, что вам придется начинать сначала по крайней мере еще раз.
Хорошо (сказал я себе), модификация fetchpop была первым блином. Поэтому я взялся за popclient.
После того, как 25 июня 1996 года я послал Карлу Харрису свой первый набор «заплаток» для popclient, я понял, что сам автор какое-то время назад утратил интерес к этой утилите. Текст был довольно «грязный», с несколькими ошибками. Мне пришлось внести много изменений и мы быстро пришли к соглашению о том, что самое логичное для меня будет взять ответственность за программу на себя.
Без моего особого к тому внимания проект разрастался. Я недолго довольствовался незначительными добавлениями к существующему POP-клиенту. Я занялся поддержкой его как единого целого, и меня переполняли идеи, которые, как я знал, вероятно приведут к серьезным изменениям.
В программистской культуре, которая вобрала в себя идею совместного использования исходных текстов, это совершенно естественный способ развития проекта. Я действовал, придерживаясь следующего принципа.
- Если вы выбрали верную позицию, интересные задачи сами вас найдут.
- Когда вы теряете интерес к программе, ваша последняя обязанность по отношению к ней — передать ее в руки компетентного последователя.
Даже не сговариваясь, Карл и я осознали, что у нас есть общая цель — создать наилучшее решение. Единственный вопрос, который волновал каждого из нас, состоял в том, могу ли я утверждать, что у меня программа окажется в надежных руках. Как только я об этом заявил, он действовал тактично и оперативно. Я надеюсь, что смогу поступить также, когда придет моя очередь.
Пользователи нужны
Итак, я унаследовал popclient. Не менее важен и тот факт, что я унаследовал и пользователей popclient. Иметь пользователей — это великолепно и не только потому, что они показывают, что ваша работа отвечает их требованиям, то есть, что вы делаете нечто нужное. Если правильно взаимодействовать с пользователями, то они могут стать соразработчиками.
Еще одна сильная сторона традиций Unix, момент, который во многом и обеспечил успех Linux, состоит в том, что огромное количество пользователей являются к тому же и хакерами. А поскольку исходные тексты открыты, они могут стать эффективными хакерами. Это может оказаться крайне полезным и значительно сократить время отладки. С незначительной поддержкой ваши пользователи будут диагностировать проблемы, предлагать варианты их решения и помогать модернизировать код намного быстрее, чем вы могли бы сделать это без их помощи.
- Воспринимая своих пользователей как соразработчиков, вы выбираете самый простой способ быстрой модернизации кода и эффективной его отладки.
Эффект такого решения очень легко недооценить. Фактически, многие из тех, кто относит себя к миру свободно распространяемого программного обеспечения, значительно недооценивали усиление этого эффекта с ростом числа пользователей и сложности системы до тех пор, пока Линус Торвальдс не показал нам обратное.
На самом деле, я считают Линуса одним из умнейших людей нашего времени и в первую очередь не потому, что он написал ядро Linux, а потому, что он предложил модель разработки Linux. Когда однажды я сказал это в его присутствии, он улыбнулся и повторил то, что он говорит довольно часто: «На самом деле я очень ленивый человек, которому нравится приписывать себе то, что на самом деле сделали другие». Ленивый как лис. Или, как написал Роберт Хайнлайн в одной из своих статей, «слишком ленивый, чтобы ошибаться».
Если оглянуться на прошлое, можно вспомнить один прецедент использования аналогичных методов и обусловленного ими успеха Linux, связанный с разработкой библиотеки GNU Emacs Lisp и архивов программ на Lisp. В противоположность «соборному» стилю разработки ядра Emacs C и большинства других инструментальных средств FSF, эволюция пула программ на Lisp во многом определялась требованиями пользователей. Идеи и режимы генерации прототипов зачастую переписывались по три — четыре раза прежде, чем обретали стабильный, окончательный вид. А свободное сотрудничество, развитие которого было обусловлено появлением Internet, как это произошло при разработке Linux, встречалось довольно часто.
Действительно, мой самый большой личный успех на поприще программирования до работы над fetchmail вероятно был связан с режимом Emacs VC, разработка которого осуществлялась по схеме Linux — я обменивался информацией по электронной почте с тремя другими разработчиками, причем до этого мне приходилось встречаться лишь с одним из них (с Ричардом Столлманом, автором Emacs и основателем FSF (http://www.fsf.org/)). Это был фронтальный модуль для SCCS, RCS (а позже и для CVS), созданный в рамках проекта Emacs, который позволял управлять версиями буквально «в одно касание». Он был создан на основе крайне ограниченного sccs.el, написанного еще кем-то. И разработка VC завершилась успешно потому, что, в отличие от самого Emacs, код для Emacs Lisp очень быстро прошел все этапы, в том числе выпуск, тестирование и усовершенствование.
Выпускай раньше, выпускай чаще
Не доведенные до конца, но часто выпускаемые версии составляют один из важнейших компонентов модели разработки Linux. Большинство разработчиков (включая меня) были уверены, что для любых более-менее нетривиальных проектов такая политика себя не оправдывает, поскольку первые версии продукта почти по определению отличаются большим количеством ошибок и вам вовсе не хочется испытывать терпение своих пользователей.
Эта вера укрепляла всеобщую приверженность «соборной» модели разработки. Если основной целью пользователей было обнаружить как можно меньше ошибок, почему тогда вы выпускали новую версию только раз в полгода (или еще реже) и работали, не покладая рук, отлаживая тексты в промежутках между этими выпусками. Именно таким образом было разработано ядро Emacs C. При создании библиотеки Lisp был использован иной подход — поскольку активные архивы Lisp находились вне контроля FSF, к которым можно было бы обратиться в поисках нового и разработать версии кода независимо от цикла выпуска Emacs.
Самый важный из них — архив Ohio State elisp впитал в себя дух и отличался многими из черт, характерных для современных крупных Linux-архивов. Но мало кто из нас действительно всерьез думал о том, что мы создаем нечто свободное от проблем, свойственных «соборной» модели разработки FSF. Одна из самых серьезных попыток мной была предпринята в 1992 году с тем, чтобы формально объединить большую часть текстов Ohio в официальную библиотеку Emacs Lisp. Я столкнулся с рядом политических проблем и по большей части потерпел неудачу.
Но годом позже, по мере роста популярности Linux, стало ясно, что этот подход обладает существенными отличиями и намного эффективнее традиционных. Открытая стратегия разработки Linux была прямо противоположна «соборному» подходу. Архивы tsx-11 и Sunsite (теперь Metalab (http://metalab.unc.edu/)) бурно развивались и распространялись большими тиражами. И все это было обусловлено неслыханно частым появлением версий основной системы.
Линус воспринимал своих пользователей как соразработчиков и делал это максимально эффективным образом.
- Выпускайте рано. Выпускайте часто. И прислушивайтесь к своим потребителям.
Открытие Линуса состояло главным образом не в том, что он это делал (в чем-то такой подход являлся давней традицией мира Unix), а в том, что он увеличил интенсивность этой работы так, что она соответствовала сложности того, что он разрабатывал. В те давние времена (в 1991 году) он не знал, что версия ядра будет выпускаться несколько раз в день! Но поскольку он формировал сообщество своих соразработчиков и использовал возможности Internet для того, чтобы это сотрудничество было как никогда эффективным, такой подход работал.
Но как он работал? И можно ли это повторить или все дело в уникальности гения Линуса Торвальдса?
Я так не думал. Безусловно, Линус чертовски отличный хакер (многие ли из нас смогли бы разработать полностью ядро операционной системы такого уровня?). Однако Линус не предложил никакого сверхгениального концептуального шага вперед. Линус не был (по крайней мере тогда) гением от программной архитектуры, таким, как скажем, Ричард Столлман или Джеймс Гослинг (автор NeWS и Java). Нет, Линус, как мне кажется, оказался инженерным гением, обладающий шестым чувством, позволявшем ему избегать ошибок и тупиковых решений, мастером по поиску наименее трудоемких путей из пункта A в пункт B. Действительно, вся архитектура Linux проникнута этим качеством и отражает, по существу, консервативный и упрощенный подход к проектированию, предложенный Линусом.
Поэтому, если часто выпускаемые версии и эффективное использование Internet как средства обмена информацией были не случайными, а неотъемлемыми компонентами инженерного гения Линуса, позволившего ему находить наименее трудоемкий путь, что же он усилил? Чего получилось в результате?
На самом деле этот вопрос уже содержит в себе ответ. Линус постоянно стимулировал и поощрял своих хакеров-пользователей, стимулом для которых стала перспектива удовлетворения собственного «Я», обусловленное причастием к этому действу, и вознагражденных тем, что они постоянно (каждый день) видят улучшения в своей работе.
Линус напрямую стремился максимально увеличить число человеко-часов, потраченных на отладку и разработку, даже возможно, за счет нестабильности в программе и разочарований пользователей, если вдруг не удастся оперативно устранить найденную ошибку. Линус вел себя так, как будто он верил в следующий тезис.
- Если привлечь большое количество бета-тестеров и соразработчиков, почти любая проблема будет выявлена очень быстро и исправлена способом, доступным каждому.
Или, если говорить не столь формально, «при достаточном количестве наблюдателей, все ошибки мельчают». Я назвал это «Законом Линуса».
Хотя первоначальная формулировка состояла в том, что «любая задача для кого-то окажется очевидной». Линус возразил, что человек, который понимает и устраняет проблему, — не обязательно и, как правило, вовсе не тот человек, который впервые охарактеризовал проблему.
«Кто-то находит проблему, — сказал он, — а кто-то ее понимает. И я бы рискнул сказать, что обнаружить проблему намного сложнее». Но суть в том, что в данном случае и то, и другое происходит достаточно быстро.
В этом, как я считаю, и состоит коренное отличие «соборного» и «базарного» стилей разработки. С точки зрения «строителя собора» от программирования, ошибки и задачи разработки сложны, коварны и уникальны. Они требуют многих месяцев тщательного изучения группой избранных с тем, чтобы убедиться, что вы устранили все из них. Отсюда и редкое появление новых версий и неминуемое разочарование, когда долгожданный вариант оказывается несовершенен.
При «базарном» подходе, с другой стороны, вы предполагаете, что ошибки в целом — незначительные явления — или, по крайней мере, они достаточно быстро станут незначительными, когда будут отданы на растерзание тысячам сгорающих от нетерпения соразработчикам, разбирающим по косточкам каждую новую версию. Таким образом, вы часто выпускаете новые варианты для того, чтобы получить больше исправлений и, в качестве положительного эффекта, вы меньше теряете в том случае, если внезапно окажется, что работа была сделана небрежно.
И все. Этого достаточно. Если «Закон Линуса» несправедлив, тогда любая система, не уступающая по сложности ядру Linux, над которой ломают головы не меньше людей, чем создавали ядро Linux, в какой-то момент времени рухнула бы под тяжестью неконтролируемых некорректных взаимодействий и ненайденных «глубинных» ошибок. Если же он верен, с другой стороны, то он достаточно хорошо объясняет относительную безошибочность Linux и тот факт, что эта операционная система работает без сбоев многие месяцы или даже годы.
Возможно это, вдобавок, не было бы таким сюрпризом. Социологи уже давно пришли к выводу, что общее мнение группы равно квалифицированных (или равно невежественных) наблюдателей более надежный предсказатель, чем мнение одного, случайно выбранного наблюдателя. Они называют это «дельфийским эффектом». Похоже, что подход, предложенный Линусом, применим даже к отладке операционной системы и, что дельфийский эффект может нивелировать сложность разработки даже такого уровня, как ядро операционной системы.
Еще одной отличительной особенностью ситуации, сложившейся вокруг Linux, и которая, наравне с дельфийским эффектом оказала существенное влияние, стал тот факт, что участники любого данного проекта определяются сами. Один из первых респондентов отметил, что вклад в разработку проекта вносят не случайные люди, а те, кто достаточно заинтересован в том, чтобы использовать это программное обеспечение, изучить, как оно работает, попытаться найти решение проблем, с которыми они сталкиваются, и действительно создать очевидно разумное решение задачи. Каждый, кто соответствую всем этим условиям, с очень большой вероятностью предложит что-то полезное.
Я признателен своему другу Джеффу Датки () за его перефразированную формулировку «Закона Линуса»: «Отладка параллелизуема». Джефф считает, что хотя отладка требует, чтобы ее участники взаимодействовали с некоторым разработчиком-координатором, она не требует серьезной координации действий между самими участниками этого процесса. Таким образом, она не становится жертвой возрастающей сложности и затрат на управления, которые могут крайне затруднить увеличение числа разработчиков.
На практике теоретические потери эффективности, вызванные дублированием работы, выполняемой отладчиками, в мире Linux почти никогда, по-видимому, не возникают. Один из эффектов политики «выпускать раньше и чаще» состоит в том, что подобное дублирование минимизируется за счет быстрой интеграции этих исправлений.
Брукс даже поделился наблюдением, касающимся замечания Джеффа: «Общие расходы на поддержку широко используемой программы обычно составляют около 40%, а то и больше, стоимости на ее разработку. Как не удивительно, но эти расходы существенно зависят от числа пользователей. Большее количество пользователей находят больше ошибок».
Большее количество пользователей находят больше ошибок потому, что с ростом их числа увеличивается количество различных способов тестирования программы. Этот эффект усиливается, когда пользователи являются соразработчиками. Каждый из них подходит к решению задачи описания ошибки, исходя из собственного восприятия, и применяя собственный аналитический инструментарий, рассматривая проблему под своим углом. «Дельфийский эффект», по-видимому, работает именно благодаря этой вариативности. В специфическом контексте отладки эта вариативность также приводит к сокращению дублирования усилий.
Поэтому увеличение числа бета-тестеров может не привести к уменьшению сложности существующей «глубинной» ошибки с точки зрения разработчика, но оно увеличивает вероятность того, что чей-то инструментарий будет соответствовать проблеме настолько, что данная ошибка покажется этому человеку очень простой.
Линус берет ответственность и на себя. В случае проявления серьезных ошибок версия ядра Linux нумеруется так, что потенциальные пользователи могут или воспользоваться последней версией, названной «стабильной» или рискнуть, стремясь приобрести новые возможности. Формально подобной тактики не придерживаются большинство хакеров от Linux, но, возможно, так оно и будет; тот факт, что всегда есть выбор, делает привлекательными обе альтернативы.
Когда роза уже не роза?
Изучая работу Линуса и создав целую теорию, объясняющую, почему он добился успеха, я решил проверить свою теорию на новом (безусловно, намного менее сложном и грандиозном) проекте.
Но первое, что я сделал — это во многом реорганизовал и упростил popclient. Реализация Карла Харриса была весьма впечатляющей, но отличалась избыточной сложностью, свойственной многим программистам, пишущим на Си. Для него главным являлся сам текст программы, а структуры данных играли вспомогательную роль. В результате текст программы был блистательным, но структуры данных создавались по мере необходимости и оказались достаточно уродливыми (по крайней мере по высоким стандартам этого опытного разработчика программ на Lisp).
Я же преследовал совсем иную цель, переписывая эту утилиту, стремясь усовершенствовать текст и структуры данных. Стремясь превратить ее в то, что было бы мне абсолютно понятно. Совсем не весело отвечать за исправление ошибок в программе, которую вы не понимаете.
В течение первого месяца работы или около того, я просто следовал идеям, заложенным Карлом в базовую архитектуру. Первым серьезным изменением, которое я сделал, стало добавление поддержки IMAP. Я реализовал ее за счет реорганизации протокольных механизмов в один общий драйвер и три таблицы методов (для POP2, POP3 и IMAP). Это и предыдущие изменения иллюстрируют общий принцип, который всегда следует иметь в виду программистам, особенно в таких языках, как Си, которые естественным образом не поддерживают динамическую обработку типов.
- Продуманные структуры данных и незамысловатый код работают намного лучше, чем любое другое сочетание.
Брукс, глава 9: «Покажите мне [код], не показывая своих [структур данных] и я по-прежнему буду пребывать в заблуждении. Покажите мне свои [структуры данных] и, как правило, ваш [код] мне не понадобиться; и так все будет понятно».
На самом деле он упоминал «блок-схемы» и «таблицы». Но учитывая произошедшие за тридцать лет культурные и терминологические изменения, смысл абсолютно тот же.
В этот момент (в начале сентября 1996 года, примерно через шесть недель с начала проекта) я начал задумываться о том, что пришла пора изменить название, поскольку в результате то, что я делал, уже не являлось POP-клиентом. Но я колебался, поскольку ничего кардинально нового в архитектуру оригинального модуля внесено не было. Моей версии popclient еще предстояло самой превратиться в новую сущность.
Все кардинально изменилось, когда fetchmail «научился» передавать полученную почту на порт SMTP. Тогда я сразу же поменял название. Но сначала поговорим о другом. Помните, выше я сказал, что решил использовать этот проект для того, чтобы проверить свою теорию о правоте Линуса Торвальдса. Каким же образом, можете вы спросить, я это сделал? Следующим.
- Я выпускал новые версии довольно «сырыми» и часто (почти всегда хотя бы раз в десять дней; а во время периодов интенсивной разработки — каждый день).
- Я наращивал свой список участников бета-тестирования, добавляя в него всякого, кто интересовался fetchmail.
- Я приглашал к обсуждению всех, кто был указан в списке бета-тестеров каждый раз, когда выпускал новую версию.
- Я прислушивался к своим бета-тестерам, задавая им вопросы относительно архитектурных решений и хвалил их всякий раз, когда они присылали «заплатки» и сообщали свое мнение.
Эффект от таких простых приемов сказался немедленно. С самого начала проекта я создавал отчеты об ошибках, с указанием квалификации большинства разработчиков, которые эти ошибки исправили, часто сопровождая эти отчеты превосходными решениями по устранению ошибок. Меня критиковали, я получал смешные письма и весьма разумные предложения относительно новых возможностей. Все это привело к следующему.
- Если вы относитесь к своим бета-тестерам как к самому ценному своему ресурсу, в результате они таковым и станут.
Одним интересным показателем успеха fetchmail является изменение размера списка бета-тестеров проекта, любителей fetchmail. В период написания данной статьи в нем было 249 человек и каждую неделю список увеличивается на два — три человека.
На самом деле, как я убедился, в мае 1997 года этот список стал сокращаться (при том, что тогда в нем было около 300 пользователей) по весьма интересной причине. Несколько человек обратились ко мне с просьбой вычеркнуть их из этого списка потому, что fetchmail, по их мнению, работает настолько хорошо, что им больше не нужно анализировать изменения, рассылаемые по списку бета-тестеров. Возможно, что это нормальный жизненный цикл зрелого проекта, создаваемого в соответствии с «базарной» парадигмой.
Popclient превращается в Fetchmail
Действительным поворотным моментом проекта стало присланное мне Харри Хочхейзером сообщение с текстом программы, реализующей передачу сообщений на SMTP-порт клиентской машины. Я практически сразу понял, что надежная реализация этой возможности в итоге позволит обойтись практически без всех остальных режимов доставки сообщений.
В течение многих недель я модернизировал fetchmail не последовательно и целенаправленно, а довольно хаотично, в то же время понимая, насколько архитектура интерфейса функциональна, но при этом уродлива — неэлегантна и имеет слишком много опций, которые, при всей их незначительности, выделяются по сравнению с другими. Опции, отвечающие за передачу пришедших сообщений в файл почтового ящика или на стандартный вывод, особенно меня раздражали, хотя я не мог объяснить, почему.
Задумавшись о перенаправлении сообщений на порт SMTP, я понял, что popclient пытается выполнять слишком большую работу. Он был спроектирован так, чтобы служить в качестве транспортного почтового агента (MTA) и в то же время выполнять обязанности агента локальной доставки (MDA). Благодаря перенаправлению сообщений на SMTP, можно было избавить popclient от обязанностей MDA и превратить его исключительно в MTA, передав функции локальной доставки другим программам, как это делает sendmail.
К чему путаница со всей сложностью конфигурации агента доставки сообщений или настройки блокировки и добавления для почтового ящика, когда порт 25 почти гарантированно доступен на любой платформе, поддерживающей протокол TCP/IP? Особенно когда это значит, что доставленное сообщение гарантированно выглядит как нормальное сообщение SMTP, инициированное отправителем, которое на самом деле и есть то, чего мы хотим в любом случае.
Отсюда можно сделать несколько выводов. Во-первых, эта идея о перенаправлении сообщений на порт SMTP оказалась самым существенным результатом, который я получил, сознательно пытаясь повторить методы, применяемые Линусом. Пользователь предложил мне колоссальную идею, и все, что мне пришлось сделать — это понять ее значение.
- Один из самых лучших способов обрести хорошую идею — это или придумать ее самому, или воспринять у своих пользователей. Иногда последнее лучше.
Интересен тот факт, что если вы всецело и правдиво до самоуничижения будете рассуждать о том, скольким вы обязаны другим людям, мир, в большинстве своем будет считать, что вы абсолютно самостоятельно сделали свое изобретение и просто от скромности весьма низко оцениваете данную вам от природы гениальность. Отличной иллюстрацией этому является случай с Линусом.
(Когда я в августе 1997 года выступал на конференции, посвященной Perl, Ларри Уолл сидел в первом ряду. И после моих слов, повторяющих мысль, высказанную в предыдущем абзаце, он воскликнул в стиле религиозных фанатиков: «Скажи им, скажи им, братец!» Все присутствующие засмеялись, поскольку они знали, что создатель Perl оказался точно в такой же ситуации).
По прошествии нескольких недель, когда проект продолжал развиваться в том же духе, я начал получать аналогичные замечания не только от своих пользователей, но и от других людей, до кого дошли мои слова. Я сохранил для себя некоторые из этих писем; когда-нибудь я снова перечитаю их, если я вдруг засомневаюсь, не даром ли я прожил свою жизнь.
Но есть и два более фундаментальных, неполитических вывода, которые применимы к любым видам проектирования.
- Часто наиболее сложные и передовые решения появляются тогда, когда вы понимаете, что ваше представление о проблеме было ошибочным.
Я попытался решить неверную задачу, продолжая развивать popclient как объединение MTA/MDA, поддерживая все виды старомодных режимов локальной доставки сообщений. Архитектура fetchmail должна быть пересмотрена с самого начала с учетом того, что он должен быть чистым MTA — компонентом обычного пути передачи почтового сообщений по Internet с поддержкой SMTP.
Когда во время разработки вы сталкиваетесь с препятствием (когда вы понимаете, что вам трудно мыслить как раньше для того, чтобы подготовить следующую заплатку), скорее всего пришло время не находить правильный ответ, а задать правильный вопрос. Возможно задачу просто необходимо переформулировать.
И я переформулировал свою задачу. Ясно, что нужно было (1) реализовать поддержку перенаправления сообщений на SMTP-порт в общем драйвере; (2) сделать это режимом по умолчанию; (3) окончательно избавиться от всех остальных режимов доставки, и в первую очередь от опций доставки в файл и доставки на стандартное устройство вывода.
Какое-то время я откладывал реализацию шага (3), опасаясь разочаровать давних пользователей popclient, которые полагались на иные механизмы доставки. Теоретически, чтобы добиться того же эффекта они могли бы сразу перейти на файлы .forward или их эквиваленты, не являющиеся разновидностями sendmail. На практике подобная «реформа» могла оказаться крайне неприятной.
Но когда я все же решился это сделать, преимущества оказались поразительно огромными. Самые сложные компоненты кода драйвера исчезли. Конфигурация радикально упростилась — больше не нужно было поддерживать функции системного MDA и пользовательского почтового ящика и думать о том, поддерживает ли базовая операционная система блокировку файлов.
Кроме того, мы избавились от единственной возможности, которая реально могла привести к потере сообщения. Если вы указывали, что сообщение нужно доставить в файл, а диск оказался переполненными, ваше сообщение просто теряется. С перенаправлением почты на SMTP такого произойти не может, поскольку модуль получения SMTP не вернет сигнал об удачном завершении сеанса до тех пор, пока сообщение не будет доставлено или, по крайней мере, не положено в буфер для последующей доставки.
Кроме того, увеличивается и производительность (хотя вам вряд ли удастся это заметить вовремя одного сеанса). Еще одно, хоть и не столь значительное преимущество, состоит в том, что руководство по работе с системой стало намного проще.
Затем мне пришлось снова реализовывать доставку через определенный пользователем локальный MDA для того, чтобы позволить обрабатывать некоторые неясные ситуации, в том числе динамические соединения SLIP. Но я нашел способ сделать это намного проще.
Мораль? Не бойтесь отказываться от устаревших возможностей, когда вы можете сделать это без потери эффективности. Антуан де Сент-Экзюпери (который прежде, чем стать автором классической книги для детей, был пилотом и авиаконструктором) сказал:
- «Совершенство архитектуры достигается не тогда, когда вы не можете ничего добавить, а тогда, когда вы не можете ничего удалить».
Когда ваша программа становиться и лучше, и проще, вы можете быть уверены в том, что она верна. И во время разработки архитектура fetchmail обрела индивидуальность, отличную от той, что он унаследовал от архитектуры popclient.
Пришло время сменить название. Новая архитектура намного больше напоминала двойника sendmail, чем старый popclient; и тот, и другой являлись MTA, но sendmail «толкал», а потом доставлял, а новый popclient «вытаскивал», а потом уже доставлял. Поэтому, после двух месяцев сопротивления, я переименовал свою утилиту в fetchmail.
Нужно отметить, что вся эта история о том, как доставка на SMTP была реализована в fetchmail, позволяет сделать намного более общий вывод. Это не только параллелизуемая отладка; это вдобавок разработка и (возможно до удивительной степени) исследование архитектурного пространства. Когда режим разработки предусматривает быстрое и многократное повторение, сама разработки и процесс усовершенствования могут стать просто особыми случаями отладки — исправлениями «ошибок, допущенных по невнимательности» в исходных функциях или концепции этого программного обеспечения.
Даже на более высоком уровне проектирования могут крайне важными оказаться размышления большого числа соразработчиков, случайно занимающихся проблемами, которые так или иначе соприкасаются с вашим продуктом. Обратите внимание на то, как подземные воды находят выход и возникает родник, или, еще лучше, как муравьи находят себе пищу: разведка ведется по многим направлениям, после чего следует использование этих результатов, чему содействует масштабируемый механизм взаимодействий. Такой подход работает просто превосходно; как это произошло с Харри Хошхейзером и мной, один из ваших агентов может найти огромный клад, рядом с которым вы ходите, всего лишь потому, что он более внимательно смотрел именно на этом направлении.
Развитие Fetchmail
Итак, у меня была аккуратная и новаторская архитектура, программа, которая прекрасно работала, в чем я был уверен, поскольку я использовал ее ежедневно, и довольно обширный список бета-тестеров. Все это постепенно навело меня на мысль о том, что мою работу больше нельзя назвать тривиальным персональным проектом, который, в силу ряда причин, может оказаться полезен и для некоторых других. У меня в руках оказалась программа, которая действительно нужна любому хакеру, имеющему Unix-компьютер и почтовое соединение SLIP/PPP.
Благодаря возможности перенаправления сообщений на порт SMTP, мой проект постепенно превратился во вполне конкурентоспособный модуль и потенциально был способен заменить собой целую категорию продуктов. Другими словами, он становился одной из тех классических программ, которые настолько эффективно решают определенный круг задач, что все альтернативные решения не только отвергаются, но и почти забываются.
Я считаю, что изначально ставить своей целью такой результат или планировать его просто невозможно. Добиться его можно только генерируя настолько мощные архитектурные идеи, что впоследствии они приведут к результатам, которые покажутся неизбежными, естественными и даже предопределенными. Единственная возможность получить такие идеи — выбирать из огромного количества разнообразных идей или иметь возможность с инженерной точки зрения оценить хорошие идеи других людей, выходя за рамки целей, которые ставили для себя их авторы.
Энди Таненбаум предложил идею создания простого «родного» Unix для ПК компании IBM с целью использования этой системы в качестве обучающего инструментария. Линус Торвальдс развил концепцию Minix намного дальше, чем Эндрю, вероятно, мог себе представить, и в результате получилось нечто превосходное. Точно также (хотя и в значительно меньшем масштабе), я воспользовался идеями Карла Харриса и Харри Хочхейзера и значительно эти идеи расширил. Ни один из нас не был изначально тем, кого люди склонны считать «природным» гением. И к тому же, большая часть научной и инженерной работы, да и решений, связанных с разработкой программного обеспечения, выполняется отнюдь не гениями от природы, в противоположность мифам, распространенным среди хакеров.
Результаты, тем не менее, оказались весьма хитроумными — на самом деле все хакеры стремятся добиться именно такого успеха. И они считали, что я мог бы установить даже более высокие стандарты. Чтобы сделать fetchmail столь хорошим, как мне сейчас это видится, я должен был бы писать программу, исходя не только из своих собственных нужд, но включить и поддерживать в ней те возможности, которые необходимы и другим людям, вне сферы моих интересов. И делать это, следя за тем, чтобы программа оставалась простой и надежной.
Первая и безусловно самая важная функция, которую я написал после того, как понял это, была многокомпонентная поддержка — возможность получать сообщение из почтовых ящиков, в которых накапливалась вся почта, адресованная группе пользователей, а затем передавать каждый из компонентов этой почты ее отдельным получателям.
Я решил добавить многокомпонентную поддержку в частности потому, что некоторые пользователи активно добивались ее реализации, но главным образом поскольку считал, что это позволит избавиться от ошибок в программе, рассчитанной на получение однокомпонентной почты, так как заставит меня работать с адресацией, используя более общий подход. Так и произошло. На то, чтобы заставить корректно работать грамматический разбор RFC 822 http://info.internet.isi.edu/in-notes/rfc/files/rfc822.txt у меня ушло очень много времени, не потому, что какой-то отдельный его компонент был сложным, а потому, что он включал в себя огромное количество взаимозависимых и вычурных деталей.
Но в результате многокомпонентная адресация стала превосходным архитектурным решением. И я знаю, почему.
n Любой инструментарий должен быть полезен для того, что вы хотите сделать, но воистину превосходный инструментарий сам заставляет использовать его так, как вы никогда не предполагали.
Такой «дополнительной» возможностью многокомпонентного fetchmail стала возможность использовать списки рассылки, сохраняя их содержание и используя дополнительные имена, на клиентской стороне соединения SLIP/PPP. Это значит, что пользователь, работающий на персональной машине через бюджет провайдера Internet, может управлять списком рассылки не полагаясь на доступ к файлам с псевдонимами, имеющимся у провайдера Internet.
Еще одно важное изменение, внесенное по требованию моих бета-тестеров, было связано с поддержкой 8-разрядной MIME-операции. Это оказалось сделать достаточно легко, поскольку я тщательно следил за тем, чтобы код оставался 8-разрядным. Не потому, что я предполагал, что может потребоваться подобная возможность, а потому, что придерживался следующего правила.
- При создании любого программного обеспечения, наделенного возможностями шлюза, следует прилагать все усилия к тому, чтобы как можно меньше искажать поток данных — и НИКОГДА не выбрасывать информацию, пока этого от вас не потребует сам получатель.
Если бы я не последовал этому правилу, реализация поддержки 8-разядного MIME оказалась бы делом крайне сложным и изобилующим ошибками. Однако, поскольку этого не произошло, то все, что я должен был сделать — это прочитать RFC 1652 http://info.internet.isi.edu/in-notes/rfc/files/rfc1652.txt и добавить тривиальный фрагмент к логике, отвечающей за генерацию заголовка.
Некоторые европейские пользователи одолевают меня просьбами добавить возможность, которая позволит ограничивать число сообщений, извлекаемых в течение сессии (благодаря чему они могут контролировать затраты в своих дорогих телефонных сетях). Я сопротивлялся этому долгое время и до сих пор не могу сказать, что полностью удовлетворен. Но если вы создаете программы в расчете на многих потребителей, вы должны к ним прислушиваться и от того, что они не платят деньги за вашу работу — ситуация нисколько не меняется.
Еще несколько уроков, полученных при работе над Fetchmail
Перед тем, как мы перейдем к рассмотрению общих вопросов, связанных с программным инжинирингом, стоит остановится на нескольких моментах, обратить внимание на которые меня заставил опыт, полученный во время работы над fetchmail.
Синтаксис файла rc содержит дополнительные «лишние» ключевые слова, которые грамматический анализатор полностью игнорирует. Англоязычный синтаксис, который они имитируют, значительно понятнее традиционных кратких пар ключевых слов, которые получаются, когда вы удаляете эти «лишние» слова.
Все это началось как довольно поздний эксперимент, когда я обратил внимание на то, сколько деклараций файла rc начинают походить на выражения миниязыка. (Кстати, именно поэтому я изменил присутствовавшее в исходном popclient слово server на слово poll).
Мне показалось, что попытка сделать этот приказной миниязык более похожим на английский может намного упростить его использование. Теперь, хотя я отнюдь не убежденный приверженец идеи «превращения команд в язык», которую иллюстрируют Emacs и HTML, а также многие ядра баз данных, я вовсе не ярый сторонник «англоязычного» синтаксиса.
Традиционные программисты обычно отдают предпочтение управляющему синтаксису, который очень точен и компактен и абсолютно не избыточен. Это культурная особенность, доставшаяся нам в наследство с тех времен, когда вычислительные ресурсы были очень дороги, в силу чего этапы грамматического разбора должны были быть максимально простыми и дешевыми. Английский язык, отличающийся практически 50%-ой избыточностью, в свете этих требований казался абсолютно неприемлемой моделью.
Это утверждение вовсе не является для меня причиной избегать англоязычного синтаксиса; я упомянул о нем здесь только для того чтобы его опровергнуть. Благодаря тому, что сейчас расценки намного снизились, краткость не должна оставаться самоцелью. В современных условиях намного важнее, чтобы язык был удобнее для людей, чем дешевле для компьютера.
Тем не менее, по-прежнему существуют причины действовать с осторожностью. Первая из них — сложность этапа грамматической разборки. Вы же не хотите увеличивать эту сложность до такой степени, чтобы она стала серьезным источником ошибок и путаницы пользователей. Вторая причина состоит в том, что попытка создать язык более похожий на английский, часто требует, чтобы «английский» на котором мы говорим, был серьезно искажен, настолько серьезно, что кажущееся сходство с естественным языком состоит в том, что он столь же запутан, как и традиционный синтаксис. (Вы можете в этом убедиться на примере множества так называемых «языков четвертого поколения» и языков запросов для коммерческих баз данных).
Управляющий синтаксис fetchmail, как представляется, избежал подобных проблем, поскольку сфера действия языка была существенно ограничена. Он ничем не напоминает язык общего назначения; используемые в нем выражения просто-напросто не являются очень сложными, поэтому вероятность того, что вы запутаетесь, мысленно переходя между весьма ограниченным подмножеством английского языка и выражениями управляющего языка, крайне мала. Я думаю, что из всего этого можно сделать чуть более общий вывод.
- Если ваш язык не является полным аналогом языка машины Тьюринга, синтаксическое разнообразие пойдет ему только на пользу.
И еще один момент касается неясности, связанной с защитой. Некоторые пользователи fetchmail обратились ко мне с просьбой изменить программное обеспечение так, чтобы оно позволяло хранить в файле rc зашифрованные пароли с тем, чтобы шпионы не могли их случайно увидеть.
Я этого не сделал потому, что на самом деле такое решение вовсе не способствует увеличению уровня защиты. Каждый, кто получил права на чтение вашего файла rc, сможет в любом случае запустить fetchmail от вашего имени — и если им нужен ваш пароль, они смогут вырезать необходимый декодер из самой программы fetchmail, чтобы этот пароль добыть.
Все, что делает шифрование паролей .fetchmailrc — это дает ложное ощущение безопасности тем людям, которые не дают себя труда серьезно задуматься. Общее правило состоит в следующем.
- Защищенная система столь же защищена, как и ее секрет. Остерегайтесь псевдосекретов.
Необходимые условия для применения «базарного» подхода
Первые читатели этой статьи часто задавали вопросы о том, какие условия являются необходимыми для того чтобы разработка, проповедующая «базарный» подход, оказалась успешной, в том числе их интересовало и то, насколько квалифицированным должен быть руководитель проекта и состояние текста программы в тот момент, когда она передается для широкого обсуждения и начинаются попытки создать сообщество соразработчиков.
Абсолютно ясно, что никто в одиночку не может с нуля создать программу, опираясь на «базарную» модель. Один человек вполне в состоянии тестировать, отлаживать и совершенствовать программу, придерживаясь такого подхода, но будет крайне сложно начать реализацию проекта в «базарном» режиме. Так не делал Линус. Так не делал и я. Для зарождения сообщества разработчиков требуется работоспособный и готовый к тестированию продукт.
Когда вы начинаете создание сообщества, вам необходимо иметь возможность предложить правдоподобное обещание. Ваша программа не должна работать особенно хорошо. Она может оказаться «сырой», ошибочной, неполной и плохо документированной. Но она в обязательном порядке должна (a) работать и (b) убедить потенциальных соразработчиков в том, что в обозримом будущем из нее может получиться нечто действительно стоящее.
Когда Linux и fetchmail были предложены публике, они имели мощную, интересную базовую архитектуру. Многие люди, представляющие себе «базарную» модель также, как и я, справедливо считают это важным, а затем переходят от этого к заключению, что руководитель проекта в обязательном порядке должен обладать превосходной интуицией проектировщика и недюжинным умом.
Но Линус позаимствовал свою архитектуру у Unix. Я же, со своей стороны, воспользовался идеями, заложенными в popclient (хотя впоследствии они претерпели существенные изменения, пропорционально в значительно большей степени, чем Linux). Поэтому так ли необходимо, чтобы руководитель/координатор проекта, разрабатываемого в соответствии с «базарной» моделью, должен быть исключительно талантливым проектировщиков или достаточно того, что он в состоянии воспользоваться талантами других?
Я считаю, что не так уж важно, способен ли сам координатор генерировать великолепные архитектурные идеи, но критически важно чтобы координатор мог разглядеть прекрасные проектные идеи, предлагаемые другими.
Это со всей очевидность подтверждают проекты Linux и fetchmail. Линус, который, как я уже заметил раньше, не был проектировщиком, способным генерировать блестящие идеи, но продемонстрировал высочайшее мастерство в поиске и оценке превосходной архитектуры и интеграции ее в ядро Linux. Кроме того, я уже рассказал о том, что самая мощная архитектурная концепция fetchmail (перенаправление сообщений на SMTP) была предложена не мной.
Первые читатели этой статьи хвалили меня, предполагая, что я сознательно недооценивал оригинальность архитектуры в проектах, реализованных в соответствии с «базарным» подходом, поскольку большая ее часть в fetchmail была создано мной, и, как следствие, я считаю ее само собой разумеющейся. Возможно до некоторой степени это правда; проектирование (в отличие от программирования и отладки) безусловно относится к областям, в которых я могу считать себя хорошим специалистом.
Но самое сложное в том, что касается разумности и оригинальность в проектировании программного обеспечения, связана с его обыденностью — вы совершенно естественно начинаете приукрашивать и усложнять то, что следовало бы сохранить надежным и простым. Некоторые из моих проектов потерпели неудачу именно потому, что я совершил подобную ошибку, но в случае с fetchmail мне удалось этого избежать.
Поэтому я уверен, что успех проекта fetchmail частично обусловлен и тем, что я сознательно ограничивал свое стремление продемонстрировать ум; это свидетельствует (по крайней мере) о том, что оригинальность архитектуры не является существенной для «базарных» проектов. И вспомните о Linux. Предположим, что Линус Торвальдс попытался, несмотря ни на что, осуществить фундаментальные инновации в архитектуре операционной системы во время разработки; насколько высока вероятность, что в этом случае полученное в результате ядро было бы столь же стабильным и успешным?
Конечно же , определенные базовые навыки программирования и проектирования просто необходимы, но мне кажется, что почти любой, кто всерьез задумывается о том чтобы начать реализацию проекта, придерживаясь «базарной» модели, обладает навыками, превышающими этот базовый минимум. В то же время общая атмосфера, свойственная сообществу сторонников свободно распространяемого программного обеспечения, удерживает людей от попыток реализации проектов разработки в том случае, если они не достаточно компетентны, чтобы довести их до конца. До сих пор, по крайней мере, это было именно так.
Кроме того, есть еще одно качество, которое обычно не связывается с разработкой программного обеспечения, но которое, на мой взгляд, имеет столь же важное значение для «базарного» проекта, как и компетентность в области проектирования, а может быть и важнее. Координатор или руководитель «базарного» проекта должен уметь работать с людьми.
Это должно быть очевидно. Чтобы создать сообщество разработчиков необходимо уметь привлекать людей, заинтересовывать их в своей работе и уметь сделать так, чтобы люди были довольны тем объемом работы, который они выполняют. Техническим специалистам предстоит проделать большой путь чтобы этого достичь, но это выходит за рамки нашего разговора. Ваши личные качества тоже имеют немаловажное значение для успеха проекта.
Это отнюдь не случайность, что Линус — прекрасный парень, который умеет понравиться людям и сделать так, что они хотят ему помочь. Это отнюдь не случайность, что я энергетический экстраверт, которому нравится работать со многими людьми и обладает некоторыми навыками и манерой поведения артистов разговорного жанра. Если вы хоть в минимальной степени способны очаровывать людей, это может серьезно помочь вам в успешной реализации проекта в рамках «базарной» модели разработки.
Социальный контекст свободно распространяемого программного обеспечения
Абсолютно верно то, что самые лучшие проекты начинались как персональные решения проблем, с которыми сам автор сталкивается ежедневно, а затем эти решения превращались в широкомасштабные проекты потому, что проблемы, которые они были призваны решать, оказывались типичными для большого класса пользователей. Это замечание заставляет нас вернуться к правилу 1 и переформулировать его так, чтобы оно приняло более «практичный» вид.
- Чтобы решить интересную проблему, начните с поиска проблем, которые вам интересны.
Так и произошло с Карлом Харрисом и унаследованным popclient, так происходило со мной и fetchmail. Но все это было понято довольно давно. Интересный момент, на котором, требует остановиться вся история развития Linux и fetchmail, — это следующий этап — эволюция программного обеспечения в присутствии большого и активного сообщества пользователей и соразработчиков.
В своей книге «Мифический человеко-месяц» Фред Брукс заметил, что увеличение числа разработчиков для реализации программного проекта, который не укладывается в отведенные сроки, приводит к тому, что реализация задерживается еще дольше. Брукс объяснил это тем, что сложность и затраты на коммуникации с ростом числа разработчиков увеличиваются как квадратичная функция, а выполняемая работа — как линейная. Это утверждение известно как «закон Брукса» и всеми воспринимается как постулат. Но если бы закон Брукса отражал всю картину в целом, проект Linux был бы невозможен.
В классической книге Джеральда Вайнберга «Психология компьютерного программирования» приводится утверждение, которое теперь, задним числом, можно считать важным дополнением к закону Брукса. В рассуждениях, касающихся «неэгоистичного программирования», Вайнберг заметил, что компании, в которых разработчики не держатся мертвой хваткой за свои тексты и привлекают других людей к поиску ошибок и возможных усовершенствований, развитие программы происходит намного быстрее, чем где бы то ни было.
Возможно, что из-за выбранной Вайнбергом терминологии его рассуждения не получили столь серьезного внимания, какого заслуживали — описание Internet-хакеров как людей неэгоистичных, может вызвать только улыбку. Но я считаю, что сегодня его аргументы звучат как никогда убедительно.
История Unix должна была подготовить нас к тому, что мы поняли, изучая развитие проекта Linux ( и то, что я проверил экспериментально, хоть и в меньших масштабах, но сознательно копируя методы, которыми пользовался Линус). Другими словами, в то время как программирование во многом остается обособленной деятельностью отдельных людей, действительно великие программы создаются тогда, когда к ним привлекается внимание и применяются мыслительные способности целого сообщества. Разработчик, который использует только собственный интеллект, работая над закрытым проектом, никогда не сможет добиться успеха другого разработчика, который знает, как создать открытый, эволюционирующий контекст, в котором исследование архитектурного пространства, фрагменты программы, поиск и исправление ошибок, а также другие усовершенствования — это результат работы сотен (а, возможно, и тысяч) людей.
Но традиционный мир Unix всячески препятствовал реализации такого подхода, что объясняется целым рядом факторов. Один из них связан с юридическими ограничениями разнообразных лицензий, торговыми секретами и коммерческими интересами. Другой (что с современных позиций кажется очевидным) состоял в том, что Internet был еще недостаточно развит.
До появления дешевых каналов Internet, существовало несколько географически компактно расположенных сообществ, чья культура способствовала торжеству того, что Вайнберг назвал «неэгоистичным» программированием, и разработчик мог легко привлечь к решению своей задачи многих опытных консультантов и соразработчиков. Лаборатории Bell Labs, лаборатория искусственного интеллекта Массачусетского технологического института, центр университета Беркли — все они известны своими легендарными и до сих пор действенными передовыми технологиями и решениями.
Linux стал первым проектом, в котором были предприняты осознанные и успешные попытки использовать весь мир, как источник талантов. Я не думаю, что лишь по чистой случайности период созревания Linux совпал с рождением World Wide Web, и что период его «детства» пришелся как раз на 1993 — 1994 годы, когда зародился рынок провайдеров Internet и наблюдался резкий рост интереса к этой Сети сетей. Линус стал первым, кто понял, как нужно играть по новым правилам, которые возникли благодаря широкому распространению Internet.
В то время как дешевый Internet стал необходимым условием развития модели, предложенной Linux, я думаю, что он сам по себе не являлся условием достаточным. Еще один важный фактор состоял в том, что был выработан стиль руководства и появилось сообщество сотрудничающих друг с другом потребителей, что в совокупности позволило разработчиками привлечь к участию в своих проектах соразработчиков и максимально эффективно использовать возможности нового средства связи.
Но в чем состоял этот стиль руководства и кто такие эти потребители? Они не могли существенно полагаться на серьезные взаимоотношения и даже, если бы могли, руководство с позиции силы не могло бы дать тех результатов, коим мы стали свидетелями. Вайнберг цитирует автобиографию известного русского анархиста XIX века Петра Алексеевича Кропоткина «Воспоминания революционера», где эта тема превосходно отражена.
«Воспитывавшийся в семье помещика, я вступил в активную жизнь, как и многие молодые люди моего времени, с огромной верой в необходимость командования, приказания, ругани, суровости и тому подобного. Но, когда в самом начале я был вынужден управлять серьезными предприятиями и иметь дело со свободными людьми, и когда каждая ошибка приводила к весьма тяжким последствиям, я начал ценить различия между действиями на командных принципах и дисциплины и действиями на принципах взаимопонимания. Первые превосходно работали на военном параде, но ничего не стоили в том, что касалось реальной жизни, и цель могла быть достигнута только благодаря упорным усилиям многих объединенных желаний».
«Упорные усилия многих объединенных желаний» — это именно то, что необходимо такому проекту, как Linux и «командный принцип» на самом деле невозможно применить к добровольцам в анархическом рае, как мы называем Internet. Чтобы эффективно действовать и конкурировать хакеры, которые хотят возглавлять совместные проекты, должны понять, как создать и побудить к действию людей, объединенных общим интересом, в режиме, смутно описываемом «принципом взаимопонимания», продекларированным Кропоткиным. Они должны изучить, как использовать «Закон Линуса».
В начале статьи я ссылался на «дельфийский эффект» как на возможное объяснение «Закона Линуса». Но на память приходят более яркие аналоги приспосабливающихся систем в биологии и экономике. Мир Linux во многом ведет себя также, как свободный рынок или экология, множество эгоистичных агентов, пытающихся максимально увеличить пользу, которая в процессе этого порождает самокорректирующийся стихийный порядок, более сложный и эффективный, чем можно было бы добиться со сколь угодно жестким центральным планированием. Именно здесь и следует искать «принцип взаимопонимания».
«Функция пользы», которую максимизируют разработчики Linux, — это не классическая экономика, а ощущение удовлетворения своего собственного самолюбия и рост авторитета среди других хакеров. (Кто-то может назвать их мотивацию «альтруистической», но это значит игнорировать тот факт, что альтруизм сам по себе — это форма удовлетворения собственного самолюбия для альтруиста). Сообщества добровольцев, которые работают таким образом, на самом деле далеко не редкость; еще один пример, в котором я сам принимал участие, — это общество любителей научной фантастики, которые в отличие от хакеров однозначно считают «признанность» («egoboo» — рост репутации одного среди других почитателей) основным стимулом работы добровольцев.
Линус, с успехом предложивший себя в качестве посредника для проекта, в котором разработка в основном осуществлялась другими, и пробуждавший интерес к проекту до тех пор, пока тот не стал самоподдерживающимся, продемонстрировал тонкое понимание «принципа взаимопонимания», предложенного Кропоткиным. Это квазиэкономическое представление о мире Linux позволяет нам увидеть, как это взаимопонимание реализуется на практике.
Мы можем рассматривать метод Линуса как способ создания эффективного рынка на основе «признанности», чтобы максимально жестко связать эгоизм отдельных хакеров с труднодостижимыми целями, которых можно добиться только в результате непрерывного сотрудничества. В проекте fetchmail я продемонстрировал (хотя и в небольшом масштабе), что методы Линуса можно дублировать, добиваясь хороших результатов. Возможно, я стремился к этому чуть более осознанно и целенаправленно, чем он.
Многие люди (и особенно те, кто сознательно избегают свободных рынков) предполагают, что культура эгоистов, преследующих лишь собственные цели, будет фрагментарной, локальной, неэффективной, замкнутой и враждебной. Но это предположение очевидно может быть опровергнуто (и это всего лишь один пример) великолепным разнообразием, качеством и степенью детализации документации по Linux. Просто поразительно как, учитывая насколько программисты ненавидят документацию, разработчики Linux создали ее в таком огромном количестве. Очевидно, что свободный рынок, опирающийся на «признанность», работает лучше с учетом того, чтобы стимулировать добродетельное, ориентированное на других людей поведение, чем хорошо финансируемые отделы по созданию документации компаний, выпускающих коммерческое программное обеспечение.
Оба проекта, связанные с созданием fetchmail и ядра Linux, показывают, что должным образом теша самолюбие многих других хакеров, способный разработчик/координатор может применять Internet для того чтобы воспользоваться преимуществами, которые дает объединение большого числа разработчиков, так чтобы не допустить превращения проекта в хаотическую массу. Поэтому, как я считаю, закон Брукса предполагает следующее.
- При условии, что координатор разработки имеет средство связи по крайней мере не хуже, чем Internet, и знает как руководить проектом без принуждения, много умов безусловно лучше, чем один.
Я думаю, что будущее свободно распространяемого программного обеспечения будет все больше и больше связано с людьми, которые знают, как играть по правилам, предложенным Линусом, людям, которые отказываются от строительства собора в пользу свободы базара. Это вовсе не значит, что точка зрения и способности личности не будут иметь никакого значения; наоборот, я считаю, что величайшие достижения в области свободно распространяемого программного обеспечения будут принадлежать людям, которые отталкиваются от собственной точки зрения и собственных способностей, затем распространяя их за счет эффективной организации свободных сообществ, связанных общим интересом.
И, возможно, не только будущее свободно распространяемого программного обеспечения. Ни один из разработчиков закрытого проекта, не может сравниться с морем талантов сообщества сторонников Linux в решении любой из проблем. Очень немногие смогли бы увлечь идеей более двух сотен (в 1999 году — шесть сотен) человек, которые принимали участие в работе над fetchmail!
Возможно, развитие культуры свободно распространяемого программного обеспечения будет триумфальным не потому, что сотрудничество — это верно с моральной точки зрения, а «накопление» программного обеспечения — ошибочно (предполагая, что вы верите в последнее, в отличие от меня и Линуса), но просто потому, что мир закрытых исходных текстов не может выиграть нарастающую гонку вооружений с сообществами сторонников свободно распространяемого программного обеспечения, которое может направить намного порядков более мощную силу на решение проблемы.
Окончание в следующем
номере журнала
The Cathedral and the Bazaar, by Eric S. Raymond
Переведено по последней версии текста от 8 августа 1999 года (см. http://www.tuxedo.org/~esr/writings/cathedral-bazaar/).
The Cathedral and the Bazaar. Eric S. Raymond. O’Reilly & Associates. October 1999. 1-56592- 724-9. 281 pages.
Большинство книг издательства O’Reilly & Associates не относятся к разряду «еще одной книги» и отмечены своеобразием, делающим едва ли не каждую из них в определенной мере событием. Но даже с учетом этого необычность новой книги The Cathedral and the Bazaar, являющейся сборником статей Эрика Рэймонда, как бы «двойная» и бросается в глаза даже до вчитывания в текст.
Начать с того, что это книга в твердом переплете с суперобложкой, без привычных для O’Reilly изображений животных или прочих гравюр 19 века. Внутреннее оформление книги (это не в полной мере касается суперобложки, о которой речь чуть позже) выполнено в строгих классических традициях, восходящих к известному мастеру книжного дела Яну Чихольду, и забавным образом контрастирует с содержанием. Впрочем, не исключено, что парадоксальность эта — кажущаяся.
Как раз о содержании получить хорошее представление можно простым переводом на русский титула и оглавления. Итак:
«Собор и базар: Размышления революционера волею случая о Linux и об открытых текстах». С предисловием председателя совета директоров и генерального директора компании Red Hat Боба Янга.
Оглавление:Предисловие Боба Янга
Почему это должно вас касаться
Краткая история государства хакеров
Собор и базар
Обживая ноосферу
Чудесный горшочек
Отмщение хакеров
Авторское послесловие: За границами программного обеспечения ?
Приложение: Как стать хакером ?
Приложение к статье «Чудесный горшочек»
Слова благодарности
(На мой взгляд, «Собор и базар» правильнее было бы перевести «Собор или базар», но не будучи лингвистом я не рискнул этого сделать; о полиморфности связок «и» и «или» см. в любом популярном учебнике по мат. логике. — В.П.).
«Случай», который привел Эрика Рэймонда в ряды революционеров — статья «Собор и базар», написанная им еще в 1997 году, но вызвавшая эффект лавины от выстрела в горах. Идея разработки программного обеспечения (а на самом деле и ИТ в целом, как об этом говорит и сам Рэймонд, и его коллеги) вдруг перешла на новый уровень популярности и оказалась широко озвучена (в том числе и за счет последовавших статей Рэймонда), и даже оформлена («движение «открытых текстов») после многолетнего «пленения» кругом не столь большого числа интеллектуалов. Своими статьями и выступлениями Рэймонд довел до массового сознания то, о чем не задумывались или не желали распространяться многие крупные разработчики ПО: о существовании иного, помимо коммерчески-лицензионного, способа разработки, проявлявшего в отдельных случаях такую эффективность, что энтузиасты заговорили о нем как о способе разработки XXI века. В самом деле: против примеров Internet и Linux трудно что возразить.
Статьи Рэймонда, собранные под обложкой книжки, и специально для этого издания отредактированные, являются не просто констатацией фактов (какими их видит автор), но и, как сказано в подзаголовке, попыткой осмыслить происходящие явления, их побудительные причины, способы проявления. Не только слог, но и стиль изложения часто сбивается на философский. Да Рэймонд проводит и собственный философский мини-анализ: так, исследуя понятие права применительно к программному обеспечению, он проводит прямую аналогию с правом на землю, как его представлял себе Локк. Он очень много рассуждает, выказывая при этом совсем недурную для программиста (прямо скажем, редкую) эрудицию, что как нельзя уместно моменту (конец века — время осмысления) и ситуации (дефицит подобного уровня анализа).
Весьма любопытно, что (полагаю без всякого давления «руки Москвы», занятой, как полагаю, другими заботами) в книге присутствуют, по меньшей мере, два явления, делающие ее ближе русскому читателю. Во-первых, это принципиальное упоминание Петра Алексеевича Кропоткина. Анархист Кропоткин в прошлом веке очень доходчиво обосновал преимущество самоорганизующейся системы над командной по части получения конечного результата.
Прямые параллели, которые проводит Рэймонд, очевидны: командный метод и нисходящая разработка — это коммерческое производство программного обеспечения, а самоорганизация и разработка «снизу вверх» — это метод открытых текстов. Забытые на Родине, идеи русского революционера сто лет спустя всходят на Западе (это, конечно, шутка, потому что идеи анархизма всегда были международными).
Второй момент чисто издательский. Издательство поместило на суперобложке изображение картины, выбранное, как признался участник проекта по выпуску книги в ответ на мой запрос, по признаку соответствия содержанию книги. Таким образом «Композиция из фигур», написанная в 1913 году Любовью Поповой, и хранящаяся в коллекции Третьяковской галереи, открывает книгу типичного американца с размышлениями в конце XX века о путях развития программного обеспечения — история не исчезает, а прихотливо являет себя в настоящем!
Владимир Викторович Пржиялковский — независимый консультант, координатор ЕАГПО, с ним можно связаться по электронной почте по адресу