СТАТЬЯ
30.09.02

Разработка программного обеспечения группой в составе одного человека


При словах "процесс разработки программного обеспечения" у некоторых возникает образ больших и пыльных стопок подшивок, набитых правилами, директивами и формами с изобилием административного жаргона. Но обычно такие залежи документов можно встретить только в очень крупных компаниях, которые пишут программное обеспечение со скоростью улитки для правительственных организаций и компаний, входящих в список первых 500. Там программное обеспечение разрабатывается в громадных помещениях армиями программистов, которыми руководят менеджеры вроде босса с "рогатой" прической из знаменитых мультиков Скотта Адамса о Дильберте.

В действительности же процесс разработки ПО не обязательно должен быть столь чудовищным. Всё зависит от объёма задания и величины организации, разрабатывающей ПО. Хороший процесс можно приспособить для любого проекта - как для мастодонта, рассчитанного на 200 разработчиков, так и для карлика, с которым справится один человек.

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

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

Сольный проект по разработке ПО

Хотя Ник, программист с двенадцатилетним опытом разработчика, предпочитает работать в одиночку, он следует четко определённому процессу. Далее приведён его дневник с описанием проекта сроком в одну неделю, который он сделал для своего старого друга Гари.

Плодотворная идея (суббота, ночь)

Сегодня вечером я встретил Гари в нашем любимом пабе. Он работает в мелкой компании менеджером по разработке ПО. Пытаясь повысить эффективность и предсказуемость процесса разработки, эта компания недавно обучила своих сотрудников процессу Personal Software Process (Персональный процесс разработки ПО). Но тут возникла следующая проблема. Ключевой элемент такого подхода состоит в том, что разработчик учитывает, сколько времени он затратил на каждый вид работы, например, сбор технических требований, проектирование, тестирование, администрирование. Но у каждого разработчика своя стратегия учёта, поэтому сбор и консолидация всех этих данных в конце недели становится настоящим кошмаром. Помощнику приходится собирать все заметки, сообщения электронной и голосовой почты, с помощью которых участники проекта оценивали, на что и сколько они затратили времени. Это приводит в уныние, поскольку в организации по разработке ПО точное измерение трудозатрат на различные операции очень важно для отслеживания производительности, определения узких мест и эффективного планирования будущих проектов.

Я предложил Гари попробовать автоматизировать трудоёмкую работу по отслеживанию трудозатрат. На экране каждого разработчика должен быть маленький таймер, которые он может активировать, связывать с названием операции, останавливать, когда уходит на обед или другой перерыв, снова запускать при возвращении, закрывать при завершении задачи. Эти данные следует надежно хранить, а в конце недели извлекать и консолидировать в электронной таблице. "Отличная идея!" - сказал Гари. - "Ник, ты можешь сделать мне такую программку? Она сэкономит мне кучу труда и времени, а значит и денег. Я заплачу тебе, сколько скажешь. Конечно, в пределах разумного. За сколько возьмешься разработать её?" Я ответил Гари, что должен как следует подумать над этим. На следующую неделю у меня не было запланировано никакой срочной работы, поэтому я вполне мог бы состряпать что-нибудь за несколько часов. Но я быстро понял, что так не годится. "Ммммм, мне надо пару дней на размышления. Приходи ко мне в офис в понедельник к 11 утра, я подготовлю предложение".

Предложение (понедельник, утро)

Оставшуюся часть выходных я думал о проекте с таймерами несколько раз, а когда я проснулся утром, у меня уже созрела идея и два варианта её реализации. Но поскольку предложенная мне задача была серьёзным деловым предложением, мне необходимо было составить серьёзное экономическое обоснование. Что именно я создам, сколько ресурсов на это затрачу? Основные затраты - моё время; кроме того, возможно, придётся купить кое-какое программное обеспечение. И наконец, какой гонорар попросить у Гари? Итак, утром я прибыл в свой офис, расчистил свой стол и разложил на нём четыре листа бумаги. На одном из них я написал вверху следующие заголовки:

Концепция

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

Персональный таймер: КОНЦЕПЦИЯ

Проблема

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

Формулирование концепции

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

Основные участники

Сценарии использования

В плане я составлю расписание на несколько дней, указав основные этапы - те точки, в которых мне придётся принимать решения либо самостоятельно, либо вместе с Гари, что более вероятно.

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

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

План

Пока ещё только 9:30, поэтому я могу перейти к следующей части работы - к плану. Для составления схемы GANNT не требуется мощного ПО, мне нужен всего лишь приблизительный план, чтобы разделить моё время на главные фазы.
Набросав план на бумаге, я решил перенести его в мой карманный планировщик. Получился следующий первоначальный план:

Monday
Tues

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

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

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

Построение. Если Гари даст мне добро на продолжение проекта и угостит изысканным "Божоле", то в среду утром я начну писать первоклассную программу, лаконичную и изящную, а затем тщательно её протестирую. Затем я попрошу Гари зайти ко мне в четверг часам к 2 с одним из своих программистов, чтобы тот опробовал мою программу на своём портативном компьютере. А во второй половине дня я исправлю то, что им не понравится.

Эту встречу в четверг я называю этапом начальной работоспособности, потому что в этот день мою программу впервые опробуют её конечные пользователи.

Передача. Это будет последний прогон. Надеюсь, это займёт всего пару часов. Закончится это выпуском программы - вероятно, я её отправлю им по электронной почте вместе со своей аппетитненькой счёт-фактурой, и всё это будет готово в четверг к концу рабочего дня.

Список рисков

Как я уже упоминал, у меня были некоторые сомнения и беспокойство. Но вместо того, чтобы зарыть голову в песок, я кратко запишу их на бумаге под заголовком "Риски". Я включу в этот список всё, из-за чего проектик может провалиться, растянуться или выйти за рамки бюджета. А записывать я буду карандашом, потому что список рисков нужно постоянно исправлять, дополнять и уточнять.

Вот этот список:

Персональный таймер: Риски

Экономическое обоснование

Сейчас 10:30, у меня есть вся необходимая информация для создания первоначального варианта экономического обоснования, поэтому я могу приступить к заполнению последнего листа бумаги. Я уже рассчитал, что проект отнимет у меня четыре дня. Возможно, мне придётся обновить компилятор Java и СУБД, поэтому я помечу эти вещи меткой TBD (пока не известно). Скорость моего подключения к Интернету невелика, может также потребоваться время на исправление возможных ошибок, поэтому не исключена значительная задержка.

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

Архитектура

Поскольку Гари ещё не пришёл, я продумываю следующий шаг. На пятом листе бумаге, озаглавленном Архитектура, я быстро набрасываю карандашом схему основных компонентов таймера: Java-аплет, браузер, база данных, экстрактор данных. Вот эта схема:

Затем, используя язык UML (унифицированный язык моделирования), я добавляю ещё пару компонентов. Поскольку схема получилась неплохая, а Гари немного разбирается в программном обеспечении, я её покажу ему.

Обязательство (понедельник, обед)

Короче говоря, Гари это понравилось. Он заплатил за обед. Я показал ему свои пять исписанных листов (и мой карманный планировщик), и мы в ожидании главного блюда замарали их ещё больше.

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

Итак, почти на лету, я подправил подготовленные этим утром документы.

Концепция, второй вариант

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

План, второй вариант

Я решил сильно не рисковать. Чтобы снизить связанный с архитектурой риск, я решил передвинуть архитектурный этап (конец фазы проработки) на обед четверга. Я запланировал выполнить фазу построения за два дня в две итерации. В среду на первой итерации я сделаю и протестирую версию, рассчитанную на одного человека, а в четверг я разработаю и протестирую сетевую функцию клиент-сервер. Поэтому фаза передачи сместиться на пятницу, а заключительная сдача программы - на вечер пятницы. Кроме того, Гари хочет, чтобы в пятницу утром я пришёл в его офис и установил бета-версию, чтобы опробовать её на месте.

Monday
Tuesday

Понедельник Вторник Среда Четверг Пятница
ОБСЛЕДОВАНИЕ
Концепция
План
Экономическое обоснование
Риски
Прототип
Снижение рисков
ПОСТРОЕНИЕ
На одного человека
Проектирование
Код
Тест
ПОСТРОЕНИЕ
Клиент-сервер
Проектирование
Код
Тест
ПЕРЕДАЧА В ЭКСПЛУАТАЦИЮ
Усовершенствования?

Начальная работоспособность: показ бета-версии

Цель: ОК от Гари.        
ПРОРАБОТКА
Прототип
Архитектура: ОК от Гари.
Сценарии использования
Тесты
Проектирование
Код
Тест
Проектирование
Код
Тест
Сдача

Список рисков, второй вариант

Теперь надо добавить пять новых рисков:

Персональный таймер: Риски, версия 2

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

Экономическое обоснование, второй вариант

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

Углубленный анализ (понедельник, вторая половина дня)

Вернувшись в свой офис, я принялся более тщательно анализировать подробности двух основных сценариев использования:

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

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

По мере того как я прорабатывал эти идеи, возникало всё больше и больше вопросов. Список операций заранее определён и не изменяется? (Наверняка нет.) Может ли любой разработчик создать новый список, или может только обращаться к существующему списку? Расспросить об этом Гари сейчас нельзя, связь с ним возможна только по голосовой почте, поэтому я записал вопросы, чтобы получить ответы завтра.

К вечеру я написал следующий аплет:

Также я написал в текстовом файле кое-какие данные операции для все тестов, которые я только мог придумать (в истинном стиле XP - опытного программиста). Неплохо для одного рабочего дня.

Запарка (вторник)

В этот день на меня обрушился "контрастный душ". Я вычеркивал из списка один риск и тут же вынужден был добавлять два новых. Я сделал немало открытий. В обеденное время я заказал пиццу в офис - я не мог позволить себе терять время, потому что пришлось решать проблемы с интерфейсом к базе данных. Программа рушилась, потому что у меня оказалась слишком старая версия программного обеспечения. Кроме того, я недостаточно внимательно прочитал спецификацию по API. На техническую поддержку, загрузку нужной версии и изучение документов ушёл ещё час.
Работа продвигалась очень медленно, и я уже начал жалеть, что связался с этим проектом. Столько подводных камней, даже в этом смехотворно крошечном приложении!

Хотя я всё же построил UML-модель. Всего лишь диаграмма с единственным классом и две диаграммы сотрудничества. При этом я также нарисовал диаграмму компонентов на основе листа с архитектурой, который я теперь мог выбросить.Остальные листы я повесил на стену.

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

Концепцию я не изменил, но теперь к ней добавилось семнадцать заметок, все с вопросами и проблемами. Я принялся добавлять такие комментарии:

Когда Гари пришёл на обед со своим коллегой Эриком, я наносил последние штрихи к прототипу, не такому уж и дурацкому. Все данные подготовлены, есть только один пользователь "Гари" и одна операция "Обдумывание", с этим я уже могу приостанавливать таймер и возобновлять его ход, что является расширением сценария использования "Измерение длительности операции". База данных запущена на моём настольном компьютере, а аплет - через сеть на моём портативном компьютере. И вот мой список рисков сократился до нескольких простых пунктов.

Мы игрались с прототипом минут пять, пока Эрик не обрушил его. Он был шокирован, но я пояснил, что такие цели, как надёжность и полнота, в данном случае не ставились. Затем мы обсудили внешний вид аплета и немного реорганизовали поля. Затем посмотрели составленный мной список вопросов. Эрик был очень обеспокоен потерей данных, которая могла произойти при перезагрузке компьютера во время работы счётчика. Я надеялся, что он не придаст этому большого значения, но пришлось пообещать разобраться с этим вопросом. Наверно, мне не надо было поднимать этот вопрос.

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

Гари был доволен и дал добро на продолжение проекта. Он не возражал против ограничений.

Чем дальше в лес, тем больше изменений (среда)

Я нашёл решение проблемы, которая беспокоила Эрика!

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

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

Примерно в 11:30 позвонил Эрик. Он забыл сообщить мне об одном требовании: сотрудник может выполнять несколько операций одновременно, поэтому следует предусмотреть возможность запускать несколько счётчиков одновременно.
Ой! Изменение концепции. Это может оказаться непростой задачей, поэтому я добавил в список рисков ещё один пункт.

Почти готово (четверг)

Тестирование. Работа над сетевыми функциями. Проблемы.

Я снова уточняю у Гари требования, пытаясь заменить то, о котором вчера сказал Эрик, на другое требование из моего списка. Я должен реализовать учёт по сочетанию операция + проект, поскольку большинство сотрудников Гари участвуют в нескольких проектах одновременно.
На основе сценариев использования я начал писать небольшое Руководство пользователя в формате HTML, которое можно читать в браузере.

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

Снова тестирование. Сначала я проверяю устойчивость к нагрузкам. Никаких проблем. Затем проверяю обновление базы данных на двух компьютерах одновременно. Плохо. Синхронизацию нужно серьёзно переделать. Ошибка: один и тот же пользователь работает на двух компьютерах одновременно при одном и том же сочетании операцию + проект; одной записи не хватает.

Ближе к ночи я нашёл причину ошибки. Теперь почти всё работает.

Бета и передача (пятница)

Утром я пришёл со своей первой бета-версией в компанию, где работает Гари. Мы установили программу на нескольких компьютерах, я настроил базу данных и проинструктировал сотрудников Гари, затем мы начали проверять программу. Я ходил со своим блокнотом от одного сотрудника к другому, записывая предложения по улучшению.

В список ошибок я добавил две серьёзных проблемы и двенадцать мелких (в основном связанных со вкусовщиной).
К обеду я уже был в своём офисе. Исправил все серьёзные проблемы и проигнорировал три мелких. Нашёл ещё четыре проблемы, в основном при систематическом тестировании. Наконец, следующая версия готова. В своей системе управления конфигурацией я присвоил ей номер 0.9. Похоже, меня ещё ожидают версии 0.91 и 0.92. Я начал впадать в отчаяние.

Поздно ночью я сделал перерыв, чтобы написать заметки к версии и сделать маленькую программу установки. К 1:00 ночи я совсем измотан. Записываю на компакт-диск с воплем "Готово! Версия 1.0!!".

Открываю светлое пиво (шампанского в холодильнике не оказалось).

Конец. По крайней мере, этот раунд закончен.

Процесс Ника

Что полезного о процессе разработке мы узнали из истории Ника? Взглянем на его действия и рассуждения внимательнее.

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

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

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

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

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

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

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

Вот суть используемого Ником очень простого процесса разработки ПО. Это "малоформальный" процесс с малым количеством артефактов и создаваемых продуктов. Тут не требуется большой работы с документами, поскольку многие артефакты хранятся в различных средствах разработки: средстве управления конфигурацией, средстве проектирования, офисных средствах и т.д. Эти создаваемые в процессе разработки артефакты полезны не только при разработке первой версии продукта, но и позже, при работе над следующими версиями и дополнительными продуктами. Если через три месяца Гари придёт и попросит Ника разработать версию 2, эти артефакты помогут Нику сделать работу быстрее и лучше. В них он почерпнёт важную информацию об оценках стоимости, о той части кода, которую можно использовать в новой версии, а также советы, которые помогут избежать повторения допущенных ранее ошибок.

Хотите верьте, хотите - нет, но применяемый Ником простой процесс содержит очень важный шаг процесса Rational Unified Process® (RUP®), и вы легко можете его повторить и при этом не корпеть над множеством сложных инструкций. Кто сказал, что RUP следует применять только для гигантских проектов, в которых участвуют сотни разработчиков? Здесь дан пример того, как процесс RUP очень эффективно используется группой из одного человека. Ник любовно называет его своим "Персональным унифицированным процессом" (Personal Unified Process), сокращённо PUP.

Литература

Kent Beck, Extreme Programming Explained: Embrace Change. Addison-Wesley, 2000.
Rational Unified Process, Rational Software, 2002.
Leslee Probasco, "The Ten Essentials of RUP." The Rational Edge, December 2000, (на русском языке)
Philippe Kruchten, "What Is the Rational Unified Process?" The Rational Edge, January 2001,
Philippe Kruchten, The Rational Unified Process: An Introduction, 2nd ed. Addison-Wesley, 2000.
Humphrey Watts, Introduction to the Personal Software Process, Addison-Wesley, 1997.

Дополнительную информацию Вы можете получить в компании Interface Ltd.

Обсудить на форуме Rational
Отправить ссылку на страницу по e-mail


Interface Ltd.
Тel/Fax: +7(095) 105-0049 (многоканальный)
Отправить E-Mail
http://www.interface.ru
Ваши замечания и предложения отправляйте автору
По техническим вопросам обращайтесь к вебмастеру
Документ опубликован: 30.09.02