Вообразите себе, что ваш почтовый ящик переполнен жалобами на программный продукт вашей разработки. Далее представьте себя в кресле менеджера, перед которым сотни отчетов об ошибках, и вам известно, что на исправление каждой из них надо в среднем семь тыс. долл. Подумайте о последствиях для имиджа вашей компании. Что скажут заказчики?

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

Путь спасения

В безвыходной ситуации имеет смысл рассматривать самые нелепые предложения. Обычно железно действует аргумент типа «Сейчас мы, по крайней мере, знаем, что у нас есть. И еще неизвестно, что мы получим, если начнем все с начала». В нашем случае мы знали, что имеющийся программный продукт не работает и терять было нечего. Был лишь шанс раз и навсегда избавиться от надоевших всем ошибок. Однако, комплекс содержал свыше пятидесяти тысяч строк Basic-подобного кода, включая около двухсот процедур ввода данных, у каждой из которых было до 25 параметров. Руководство предлагало взять за основу новой разработки концепцию «чистой комнаты» (Cleanroom), чтобы переработать продукт за 6 месяцев.

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

Затем руководство выбрало четырех разработчиков - по одному из каждой группы, изначально принимавших участие в проекте, одного опытного тестировщика и еще двух новых человек со стороны. У этих двоих было много новых идей и лишь ограниченные знания программного продукта - они принадлежали к типу людей, которых Ичек Эдайзес [1] назвал бы антрепренерами (таблица 1). Один из отобранных четырех сотрудников, ранее занятых в проекте, казался сильно смущенным тем, что именно при его участии проект был заведен в тупик. Он и тестировщик предпочитали работать ради четко поставленной цели. По классификации Эдайзеса они принадлежали к типу исполнителей - тип людей, которые считают, что день пропал даром, если они к его концу ни написали ни строчки кода.

Шанс на успех

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

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

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

Реорганизация процесса реинжиниринга (метаинжиниринг) выявила скрытые переменные проекты и обеспечила более глубокий взгляд на сам механизм разработки программного продукта. Я пришел к выводу, что мы пренебрегли третьей, наиболее важной точкой зрения, мы никогда не рассматривали человеческий аспект - как человек взаимодействует с процессом и задачами [2]. В этом плане анализ команды разработчиков, соответствующих перечисленным в таблице 1 типам сыграл значительную роль, помог объяснить почему за первые три недели проект зашел в тупик. Мы должны были определить, какой процесс более всего подходит группе разработчиков, с доминировавшими в ней энтузиастами-исполнителями и генераторами идей, которые не были экспертами в технической области, но стремились конструктивно решить задачу.

Два процесса реконструкции

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

Как показано на рис. 1а, для процесса «А» мы должны были еще до начала процесса реконструкции системы и до начала перепроектирования построить один «черный ящик» для целой системы. Затем проект разбивается на две группы: одна - для анализа сверху вниз начальных спецификаций высокого уровня, вторая - для анализа программного снизу вверх. Обе группы должны были использовать отчеты об ошибках для построения черного ящика: таблицы с перечнем стимулов, откликов и соответствующей истории стимулов. Истинно «черный ящик» создается в результате обсуждения конфликтов путем сравнения.

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

В процессе «B» фаза начального анализа намного короче (рис. 1б) - вместо построения черного ящика вы должны использовать оригинальные спецификации высокого уровня вместе со структурой кода для анализа общей модели или архитектуры задачи. Другими словами, вы создаете «прозрачный ящик» из большого количества маленьких черных.

На основе принятой модели системы происходит разработка и перестройка «ящиков». Если, например, в модели предписан «блок» (или модуль), называемый «Управление операциями», вы должны проверить спецификации верхнего уровня для уточнения его функциональности. Затем проанализировать код для локализации строк, отвечающих за выполнение этих функций. Двигаясь далее по коду, сформируйте спецификации соответствующего «блока». Здесь можно столкнуться с тремя различными ситуациями.

  • Если очевидно, что «прозрачный ящик» отвечает всем требованиям, то напрямую внесите изменения логики и затем интегрируйте модуль в программное обеспечение.
  • Если это не очевидно и только построение «блока состояния» может сделать это очевидным, внесите изменения в «блок состояния» и продолжайте работу над созданием «прозрачного ящика», а затем интегрируйте его в ПО.
  • Если это необходимо для проверки функциональности, постройте и «черный блок», и «блок состояния», затем внесите исправления на уровне «черного блока», и постройте новые «блок состояния» и «чистый блок». Затем интегрируйте переработанные модули в программное обеспечение.

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

В поисках лучшего процесса

Наша работа началась в соответствии с планом процесса «А» - мы разбились на две подгруппы для работы «сверху вниз» и «снизу вверх». Руководитель проекта и консультанты занимались определением процесса. Очень скоро возникло большое количество проблем: построение «черного ящика» для 50 тыс. строк кода - огромная и нудная работа, а заполнять бесконечное число таблиц воздействий и ответов на них было довольно скучно. Груды бумаг росли и встал вопрос, когда и как сравнивать результаты восходящего и нисходящего методов проектирования. Сравнение вызывало конфликты между людьми, вовлеченными в проект.

Руководитель проекта назначил кризисное совещание, где спрашивал о нашем продвижении за первые три недели, которое мы оценили в 5%. Итак, четыре человека выполнили 5% работы за три недели. Это значило, что для завершения всего проекта может потребоваться 60 недель вместо изначально отведенных 24. В тот момент мы имели фатальную систему программного обеспечения, фатальный процесс и напряженную атмосферу, благодаря ссорам по поводу методов организации работы.

Несколькими днями позже мы начали работать в соответствии с процессом «B», который очень не нравился консультантам, но начальнику отдела он казался более оперативным. Сразу же исчезло непонимание нами же определенных процессов, а формирование блоков из старого кода и их реконструкцию мы находили творческим и даже веселым занятием. Благодаря итерациям и повторному интегрированию этих блоков в систему мы имели дело с модулями, которые тестировали совсем недавно. Чем дальше мы работали вместе, тем более формировался позитивный дух. С каждой маленькой победой успех становился все более очевидным. Группа стала единой командой.

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

Тяжелый хлеб программиста

Анализ приведенного случая затрудняется наличием трех предысторий: история о реконструкции неработающего программного продукта, история о двух процессах разработки и история о людях, вовлеченных в проект. Каждая история интересна по-своему. Реконструкция относится к тому виду деятельности, когда модернизируются унаследованные системы, улучшения процесса разработки становятся жизненно важными для конкурентоспособности компании, а мотивация сотрудников всегда была решающим фактором. Однако чтобы понять, почему работа в соответствии с процессом «А» провалилась, а процесс «В» достиг успеха, требуется рассмотреть проект со всех трех точек зрения.

Первое объяснение - процесс не соответствовал задаче. Метод блоков не масштабируется до программ размером в 50 тыс. строк кода, а результирующий процесс может оказаться слишком длинным и входные данные не будут подходить к выводимому процессу. Более того, интерактивность процесса «В» на ранних стадиях сделала его более оперативным, потому что он обеспечивал лучшее программное обеспечение почти с первого дня.

Второе объяснение сводится к тому, что процесс не соответствовал вовлеченным в него людям - разработчики были по натуре антрепренерами и исполнителями, а процесс «А» требовал администраторов. Наибольшая разница между процессами, возможно, состояла в смеси анализа и синтеза. Имея группу исполнителей без больших технических знаний, важно выбрать такой процесс, чтобы для их рук быстро нашлось конкретное дело. В этом плане процесс «В» с ранней стадией синтеза лучше подходит для смешанной группы людей и такая команда имеет больше шансов на успех.

Кроме этого, возможность разработчикам самим определять процесс (как было предусмотрено в «В») гарантирует его понимание и обеспечивает мотивы для творческой деятельности.

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

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

Фокусирование на самом процессе (как, например, SW-CMM [3,4]) не обеспечивает достаточной информации для понимания и повышения производительности компаний, производящих ПО. Конечно, легче сказать, чем сделать, потому что сколько человек столько и различных интересов и приоритетов, которые могут снижать общий уровень оптимизации. Однако вы еще должны всегда сохранять целостный взгляд на процесс разработки, чтобы за проектом не потерять людей. Уважение их индивидуальности, обеспечение им возможность самим определять процесс помогает достичь успеха. Нельзя недооценивать силу и возможности сотрудников.

Об авторе

Аллан Джэкобсон, владелец компании MindMate, работает как консультант по улучшению процессов разработки программного обеспечения. Его деятельность в программной индустрии связана с поддержкой, проектированием, кодированием, тестированием и проверкой качества. Связаться с ним можно по электронной почте: baktoft@mindmate.dk

Литература

1. I. Adizes, How to Solve the Mismanagement Crisis. MDOR Inst., Los Angeles, 1979.

2. J. Bach. «Enough about Process: What We Need Are Heroes», IEEE Software, Vol. 12, No. 2, Mar./Apr. 1995, pp. 96-98.

3. W.S. Humphrey, Managing Technical People, Addison-Wesley, Reading, Mass., 1997.

4. J. Bach. «The Immaturity of the CMM,» American Programmer, Sept. 1994, pp. 13-19.


Software processs: Live and let die, Allan B. Jakobsen. IEEE Software, May/June 2000, pp. 71-75. Reprinted with permision, Copyright IEEE CS, 2000. All Rights Reserved.


Концепции «ящиков»

Основная идея метода «чистой комнаты» заключается в том, что программное обеспечение рассматривается как система, преобразующая входные данные или воздействия, в специфические выходные данные или отклики, определяющиеся историей предыдущих воздействий (рис. А).

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

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

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

История воздействий
Черный ящик =>=>=> потоки
Блок состояния=>Структура данных=> сверху вниз
Прозрачный ящик=>Структура данных+логика (или система черных ящиков)=> снизу вверх

Рис. А. Методика «ящиков»

Литература

H.D. Mike, R.C. Unger, and A.R. Hevner. Principles of information Systems Analysis and Design. Academic Press, San Diego, Calif., 1986


Таблица 1. Типы разработчиков
ТипОпределение
АнтрепренерМечтатель, генератор новых идей
АдминистраторНадсмотрщик за структурой и порядком, предпочитает работать сразу над несколькими задачами
ИсполнительРаботяга, требует конкретных целей, предпочитает выполнять только одну задачу
ИнтеграторОтец семейства, заботится о социальном взаимодействии, лучше работает в гармоничной среде

Рис. 1 (а) Процесс «А» основывается на построении «черного ящика» до начала проектирования; (б) Процесс «B» вовлекает в разработку «прозрачного ящика» много «черных ящиков»