Книга: Джоэл и снова о программировании
Назад: Глава тридцать пятая. Пять почему
На главную: Предисловие

Глава тридцать шестая. Установите приоритеты

12 октября 2005 года, среда

Пора было заканчивать возню с FogBugz 4.0 и начинать работать над 5.0. Мы только что выпустили большой пакет обновлений, исправив тьму мелких ошибок, которые никто никогда не заметил бы (и добавив пару новых мелких дефектов, которые тоже никто никогда не заметит), и пора было добавлять настоящие новые функции.
К тому времени, когда мы собрались начать разработку, идей было столько, что хватило бы для 1700 программистов на пару десятилетий. К сожалению, у нас было всего три программиста, а выпустить новую версию мы планировали следующей осенью, так что пришлось расставить некоторые приоритеты.
Прежде чем рассказывать о том, как мы упорядочили свой список функций, приведу два примера того, как это делать не нужно.
Случай первый: если вдруг окажется, что вы собрались реализовать функцию, обещанную одному клиенту, в вашем мозгу должна загореться КРАСНАЯ АВАРИЙНАЯ ЛАМПОЧКА. Если вы делаете что-то для одного клиента, это значит, что либо ваш агент по продажам совершенно вышел из под контроля, либо вы начали опасное скатывание в сторону консалтингвера 16 (consultingware). Ничего дурного в консалтингвере нет: скатывание в него происходит достаточно комфортно, но такой продукт приносит меньше прибыли, чем коробочный.
Коробочный продукт — это модель разработки, при которой покупатель берет все или ничего. Разрабатываете программу, делаете для нее упаковочную коробку, и покупатель либо берет ее, либо нет. Вопрос о том, что клиент купит продукт, если в него будет добавлена еще одна функция, не ставится. Никто не приглашает вас, чтобы обсудить, какие функции должны быть в программе. Нельзя позвонить в Microsoft и сказать: «Послушайте, мне нравится в вашем Excel функция BAHTTEXT для записи чисел прописью на тайском языке, но я хотел бы воспользоваться такой же функцией для английского языка. Я куплю Excel, если вы реализуете там эту функцию». Потому что если вы звоните в Microsoft, то слышите следующий ответ:
«Спасибо, что обратились в Microsoft. Если у вас есть специальный четырехзначный рекламный код, нажмите 1. Для получения технической поддержки по всем продуктам Microsoft нажмите 2. Для предпродажного лицензирования Microsoft или получения информации о программе нажмите 3. Если вы знаете номер сотрудника Microsoft, с которым хотите переговорить, нажмите 4. Чтобы повторить это сообщение, нажмите звездочку».
Понятно? Нигде не сказано: «Для обсуждения того, какие функции нужно добавить в наши продукты, чтобы вы их купили, нажмите 5».
Разработка под клиента — темная история. Клиент говорит вам, что нужно сделать, а вы спрашиваете: «Вы уверены в этом?», и он подтверждает, и вы пишете совершенно замечательную спецификацию и спрашиваете: «Вы этого хотите?», и он подтверждает, и вы заставляете его подписать спецификацию несмываемыми чернилами (нет, кровью!), и он подписывает, и вы создаете то, под чем он подписался, — быстро и точно — и показываете клиенту, и он в ужасе и шоке, и до конца недели вы выясняете, включает ли в себя ваша страховка от ошибок и упущений покрытие судебных расходов в тяжбе, в которую вы ввязались, или только стоимость урегулирования претензий. Либо, если очень повезет, заказчик вяло улыбнется и уберет ваш код в ящик, чтобы никогда им не пользоваться и никогда больше вам не звонить.
Консалтингвер занимает некоторое промежуточное положение: вы якобы делаете коробочный продукт, хотя на самом деле — заказное программное обеспечение. Вот как это происходит:
1. Вы работаете по найму и пишете код для обувной фабрики, а
2. Фабрике нужна программа для наведения глянца на ботинки, поэтому
3. Вы пишете программу полировки ботинок на VB 3.0 с элементами JavaScript, Franz Lisp и базы данных FileMaker, которая работает на старом Маке, подключаемом к сети по AppleScript, после чего
4. Все говорят, что программа первый сорт, и поскольку вы всегда мечтали создать собственную софтверную компанию, а то и стать кем-то вроде Билла Гейтса или хотя бы Ларри Эллисона, то
5.    Вы покупаете у своей прежней фирмы права на ShoeShiner 1.0 и находите венчурный капитал, чтобы основать собственную фирму ShoeShiner LLC, которая рекламирует ПО для полировки ботинок, но
6. Никто из бета-тестеров не может заставить ваш продукт работать из-за неясной зависимости от AppleScript и жестко прошитого в исходном коде IP-адреса, поэтому установка у каждого клиента занимает месяц, и
7. Трудно находить клиентов, потому что ваш продукт очень дорог из-за всех этих расходов на установку, включающих в себя древний Macintosh IIci под System 7, который приходится покупать на eBay в музеях компьютеров, так что ваши инвесторы начинают нервничать, пытаясь
8. Прижать агента по продажам,
9. Который обнаруживает, что одному из ваших потенциальных клиентов не нужно полировать ботинки, но вот программа для утюжки брюк ему действительно пригодилась бы, и
10. Агент по продажам — чего еще от него можно ожидать — продает программу для утюжки брюк за 100 K долларов,
11. И теперь вы полгода пишете этому клиенту уникальный «модуль для утюжки брюк»,
12. Который никогда не понадобится больше никому, поэтому, фактически,
13. Во всех практических смыслах тот год, что вы потратили на поиски инвесторов, можно было спокойно работать на жалованье в компании, шьющей брюки; GOTO 1.
Не спешите, лучше постарайтесь держаться той стороны, где делают коробочный продукт. У такого продукта нет маргинальных затрат на каждого нового покупателя, поэтому, в сущности, вы продаете одну и ту же вещь снова и снова, зарабатывая гораздо больше. Более того, вы можете снизить цену, потому что делите издержки разработки на гораздо большее количество клиентов, а снизив цену, получаете новых покупателей, потому что многие вдруг осознают, что ваш подешевевший продукт достоин внимания, и жизнь прекрасна, и все чудесно.
Поэтому если вдруг окажется, что вы реализуете функцию только потому, что она обещана клиенту, значит вы сдвигаетесь в область консалтинг-вера и заказных разработок, что прекрасно, если вам это нравится, но там нет таких возможностей получить прибыль, как с коммерческими коробочными продуктами.
Это не означает, что не нужно прислушиваться к своим клиентам. Я, например, считаю, что пора бы Microsoft действительно реализовать версию функции BAHTTEXT для тех из нас, кто еще не приобщился к мировой экономике и не выучил тайский, по старинке выписывая чеки в других валютах. На самом деле, если вам очень хочется думать, что лучший способ применения ресурсов разработки — позволить своим крупнейшим клиентам делать «заявки» на функции, что ж, можно поступить и так, но вскоре вы убедитесь, что крупным богатым клиентам требуются функции несколько иного рода, чем массовому рынку, и что новая функция для работы с такой денежной единицей, как бат, мало помогает повысить продажи Excel для курортов в Скоттсдейле (Аризона), и в реальности вы лишь отдаете разработчиков в кабалу агентам по продаже, единственная цель которых — увеличить свои комиссионные.
Идя таким путем, Биллом Гейтсом не стать.
А теперь я расскажу о втором пути, по которому не надо идти, принимая решение о том, какие функции следует реализовать. Не делайте чего-то только потому, что это неизбежно. Неизбежность — планка недостаточной высоты. Сейчас поясню.
Как-то на первом году жизни Fog Creek я раскладывал какие-то документы и обнаружил, что у меня кончились синие папки.
Дело в том, что у меня есть система. Синие папки относятся к клиентам. Папки цвета манильской пеньки — для служащих. Красные папки — денежные поступления. Все остальное желтого цвета. Мне нужна была синяя папка, а они кончились.
И я сказал себе: «Все равно мне понадобятся синие папки, так что пойду сейчас в Staples и куплю их».
Разумеется, это было пустой тратой времени.
Размышляя об этом позднее, я понял, что уже давно занимаюсь всяким dumb shit (это технический термин) только потому, что считал: раз все равно придется этим заниматься, то можно сделать это прямо сейчас.
Под этим предлогом я пропалывал сад, заделывал дырки в стенах, сортировал диски MSDN (по цветам, языкам и номерам) и так далее, вместо того чтобы писать или продавать код — единственное, чем действительно стоит заниматься в начинающей компании.
Иными словами, я просто делал вид, что все задачи, которые надо было решить, имеют одинаковую важность, а потому, раз они все равно неизбежны, то можно решать их в любом порядке! Во как!
Честно говоря, я просто откладывал дела на потом.
Что я должен был сделать в действительности? Для начала, следовало избавиться от фетишизма в отношении цвета папок. Нет никакой разницы. Совсем не обязательно иметь для папок цветовой код.
А что с этими дисками MSDN? Да бросить их в большую коробку. Идеально.
Но главное, я должен был раньше понять, что «важность» — величина не двоичная, а аналоговая. Есть самые разные степени важности, и если вы будете пытаться делать все, вы никогда не сделаете ничего.
Поэтому если хотите добиться успеха, в каждый данный момент времени вы должны безусловно знать, какая задача сейчас главная, и если вы занимаетесь чем-то другим, значит, двигаетесь вперед не самым быстрым из возможных способов.
Медленно, но я отвыкаю от привычки медлить. Я оставляю менее важные дела на потом. Одна милая дама из страховой компании надоедала мне целых два месяца, требуя данные для возобновления нашего полиса, а я не давал ей эти данные, пока она не потребовала их в пятидесятый раз, строго предупредив, что наша страховка закончится через три дня. Думаю, это правильно. Я начал подозревать, что если у вас на столе полный порядок, это может свидетельствовать о том, что вы недостаточно эффективно работаете.
Совершенно убийственная мысль!
Итак, не нужно реализовывать функции только потому, что ваш агент по продажам клятвенно обещал какому-то одному из ваших клиентов, что они будут сделаны, и не нужно реализовывать первыми маловажные/раз-влекательные функции только потому, что «все равно в итоге придется их делать».
Вернемся все же к нашей теме — выбору функций для FogBugz 5.0. Вот как мы впервые упорядочили их.
Сначала я взял пачку карточек размером 5x8, записав на каждую по одной функции. Затем я собрал всю команду. Мой опыт показывает, что такой способ действует, когда собирается до двадцати человек, причем полезно пригласить тех, чьи точки зрения на все различны: программистов, проектантов, тех, кто общается с клиентами, агентов по продажам, менеджеров, составителей документации, тестеров и даже (!) клиентов.
Я также попросил всех прийти на совещание со своим личным списком идей относительно будущих функций. В первой части совещания мы вкратце прошлись по всем функциям, с тем чтобы у всех было примерно одинаковое общее представление о каждой из функций и чтобы для каждой функции была заготовлена карточка.
Идея была в том, чтобы на этом этапе не спорить о достоинствах каждой функции, и не проектировать ее, и даже не обсуждать, а просто составить приблизительное представление о ее сути. Вот некоторые из функций, предлагавшихся для FogBugz 5.0:
Персонализация исходной страницы
Удобное составление графиков
Учет оплачиваемого времени
Ветвление ошибок
(Еще 64 функции...)
Весьма туманно. Напоминаю, что в тот момент нас не интересовало, как должна быть реализована каждая функция или что для нее требовалось, потому что нашей целью была грубая расстановка приоритетов, на основе которой можно начинать разработку. В результате мы составили список примерно из 50 крупных функций.
Во второй части мы прошлись по всем функциям, и каждый из присутствующих проголосовал по каждой функции: просто «за» или «против». Никакого обсуждения, ничего больше: большой палец вверх или большой палец вниз по каждой функции. В результате выяснилось, что четырнадцать функций собрали очень слабую поддержку. Я выкинул все функции, получившие один-два голоса, оставив тридцать шесть потенциальных функций.
Затем мы назначили «цену» каждой функции по десятибалльной шкале: быстро реализуемая функция получала 1, а функция-монстр— 10. Здесь нужно помнить, что задачей было не планирование разработки функций, а их разделение на группы — мелкие, средние и крупные. Я поочередно называл функции, предлагая разработчикам оценить каждую как «маленькую», «среднюю» или «большую». Даже не зная, сколько времени займет реализация функции, легко прикинуть, что «ветвление ошибок» — «маленькая» функция, а нечто туманное вроде «персонализации исходной страницы» — «большая». Исходя из общих оценок и моих собственных представлений, мы определили стоимость всех функций:
Снова подчеркну, что все это довольно нестройно, неточно и не важно. Вы же не составляете сейчас график работы — вы просто расставляете приоритеты. Нужно только прикинуть, что за один и тот же промежуток времени можно сделать две средние функции, или одну большую, или десять маленьких. Большая точность здесь не нужна.
На следующем этапе мы составили меню из всех тридцати шести предложенных функций и их цен. Каждый из участников получил один экземпляр меню и 50 долларов на расходы. Можно было как угодно потратить деньги в пределах 50 долларов. Разрешалось купить половинку функции или двойную функцию. Тот, кому очень понравился «учет оплачиваемого времени», мог потратить на эту функцию 10 или 15 долларов; тот, кому она нравилась лишь отчасти, мог потратить на нее 1 доллар в расчете, что ее профинансируют другие.
Затем мы просуммировали, сколько потрачено на каждую функцию:
Наконец, я поделил истраченную сумму на цену:
А потом отсортировали функции по полученному коэффициенту, чтобы определить самые популярные:
Готово! Вот список всех функций, которые можно реализовать, примерно в порядке общих представлений о том, какие из функций наиболее важны.
А теперь можно заняться уточнением. Можно связывать между собой функции, естественным образом тяготеющие друг к другу, например, составление графиков облегчает учет времени, поэтому имеет смысл реализовать обе функции вместе или ни одной. А иногда, глядя на упорядоченный список, вы видите, что в нем явно что-то перепутано. Так переставьте местами! Здесь ничто не высечено на камне на века. Менять приоритетность можно даже во время разработки.
Но больше всего меня поразило то, что в итоге мы получили список, который очень хорошо устанавливал приоритеты для FogBugz 5.0 и действительно отражал общее согласие в отношении сравнительных приоритетов разных функций.
Мы начали реализацию функций примерно в порядке списка приоритетов, чтобы завершить ее к марту, чтобы, покончив с добавлением новых функций, перейти к этапу интеграции и тестирования. Для каждой (неочевидной) функции перед реализацией составляется спецификация.
(Ворчливые счетчики очков в соревновании BDUF/Agile 17 должны быть окончательно сбиты с толку. «Он за кого — за BDUF? Или за Agile? Чего он хочет? Может он хоть раз определить свою позицию?»)
Весь процесс планирования занял три часа.
Если вам повезло и у вас есть возможность выпускать новые версии чаще, чем это удается нам (см. главу 34), все равно нужно действовать в соответствии с упорядоченным списком — просто вы можете чаще останавливаться и выпускать новую версию. Частый выпуск версий хорош тем, что можно регулярно переупорядочивать список, основываясь на реакции пользователей, но такую роскошь допускает не каждый продукт.
Майк Конте (Mike Conte) научил меня этой системе во время планирования выпуска Excel 5, когда мы справились с задачей за пару часов, собрав примерно два десятка людей в конференц-зале. Самое замечательное, что примерно 50% функций, на которые у нас не хватало времени, в действительности оказались глупыми, и без них Excel только выиграл.
Система не идеальна, но это лучше, чем ходить в Staples за синими папками. Вот так-то.

 

***

16 По определению Джоэла, консалтингвер — разновидность коробочного продукта, для работ по настройке и установке которой требуется целая армия консультантов, что обходится недешево. — Прим, перев.
17 BDUF — детальное проектирование, Agile — ускоренное программирование. — Прим. перев.

 

Назад: Глава тридцать пятая. Пять почему
На главную: Предисловие