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

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

На что надо обращать особое внимание? На что направлены наши поиски? Что вызывает наши споры? Какие моменты наиболее показательны?

Системы, подсистемы и программное обеспечение

«Закон Мьюира: Как только мы захотим отделить какой-нибудь объект от других, мы обнаружим, что он связан со всем на свете».

Общесистемная незамкнутость

Существует только одна система — Вселенная. Все другие системы можно называть так только с натяжкой: они не замкнуты.

Какую систему мы имеем в виду, говоря о системе здравоохранения Соединенных Штатов? О системе, очерченной на рис. 6.1 сплошной линией? Или пунктирной линией?

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

Взгляд сверху вниз

Если бы я руководил более или менее крупной компанией, я стремился бы к тому, чтобы платежные ведомости печатались в срок, а при резервировании билетов на самолеты не возникало никаких ошибок. Предположим, что ведомость подготавливается недостаточно эффективно или ее подготовка затягивается. Придется мне самому исследовать возникшую проблему. Я буду изучать дела уровень за уровнем. Начну я с человека, отвечающего за ведомости, и попрошу его описать мне систему сверху вниз. Он может разбить систему на пять компонент: 1) процедуры; 2) люди; 3) вычислительные машины/системы; 4) входные данные и 5) распределение. На этой стадии у меня возникает возможность более глубоко ознакомиться с любой из этих пяти компонент. Поскольку нас интересует вычислительная сторона дела, я попрошу описать мне следующий уровень разбиения именно области вычислений. Это разбиение приведено на рис 6.2.

Можно заметить, что отдельные элементы второго уровня сложнейшим образом переплетаются между собой. Выбор покупаемых нами дисплеев (аппаратура) и то, что мы собираемся на них высвечивать, очень сильно влияет на 1) процедуры и 2) людей, а возможно, и на 4) входные данные и 5) распределение. Помните, существует только одна система — Вселенная, все остальные системы имеют прорехи! Теперь перейдем к третьему уровню (рис. 6.3). Пока мы отбросим подсистемы 1, 2, 4 и 5, в реальной же ситуации этого сделать нельзя (описывать эти подсистемы нам не позволяет размер книги). Все нами сказанное остается верным и при переходе на уровень 4 (см. также рис. 6.3).

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

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

Ограниченный объем книги опять не позволяет нам привести полный список всех выполняемых отдельных программ. Мы могли бы и должны были бы продолжить составление диаграммы уровня 7, на которой надо показать модули всех программ, но опять-таки на это не хватает места. Матричная диаграмма в табл. 6.1 показывает, какого рода подробности нам необходимы. Теперь, если выяснится, что все проблемы относятся к области «чистой выплаты», мы начнем изучать и тестировать модули, влияющие на чистую выплату.

Таблица 6.1. Программы, выполняемые для печати платежных ведомостей

Программа Размер Автор
Программа выписки чеков 8402 Стп [34] Джонсон А. Д., отдел 4
Печать квитанций 462 Стп Шварц М. Д., отдел 5
Программа 892 Стп Дэниэлс Р. М., отдел 11
Удержания из заработной платы 44 °Стп Абадан Д. Р., отдел 442
Расчет даты 414 Стп Уитерс М. Р., уволился
Отчет по налогам штата 317 Стп Джонсон А. Д., отдел 4
Расчет профсоюзных взносов 219 Стп Трэверс Д., отдел 41
Печать профсоюзных взносов 44 Стп Трэверс Д., отдел 41

Мы достигли достаточно точного и подробного видения проблемы. Ограничимся рассмотрением уровня 6, поскольку он более удобен для записи и чтения, хотя на практике лучше работать с более подробным уровнем 7. Мы хотим отметить все, что выполняется во время использования. Нам нужно для этого перечислить все программы, их размеры и их авторов. Результаты сведены в табл. 6.1.

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

Мы не ждем, что А. Д. Джонсон, автор программы выписки чеков, будет понимать, каким образом СУБД выполняет возложенные на нее обязанности. Мы можем лишь требовать от него, чтобы он знал, что может делать СУБД, как обратиться к ней с требованием выполнить работу, как проверить, что работа выполнена.

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

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

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

Различные подсистемы обработки данных в одной системе

Система состоит из множества подсистем — одна из них обычно есть вычислительная система, например система наземного контроля. Но и во всех других подсистемах тоже могут быть и вычислительные машины, и программное обеспечение! (См. рис. 6.6.) Вычислительные машины и программное обеспечение могут входить в состав любой подсистемы как ее часть. Спутниковая подсистема может иметь в своем составе сразу несколько вычислительных машин, на каждой из которых имеется свой комплект программного обеспечения (см. рис. 6.7).

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

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

Отделение программного обеспечения от аппаратуры

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

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

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

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

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

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

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

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

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

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

Стоимость и график разработки предсказать невозможно

Термин «разработка» используется настолько широко, мы так часто ею заняты, что иногда вводим себя в заблуждение и начинаем думать, что полностью владеем этим процессом. Всякий сразу согласится с тем, что затраты и результаты исследований предвидеть нельзя. И каждый сразу же согласится с тем, что производство даже очень сложной продукции можно и контролировать и предсказывать. Ну а что же такое разработка? В словаре говорится, что разработка это 1) «постепенное развертывание» и 2) «воплощение в жизнь». Разработка не относится к изученным и просчитанным видам человеческой деятельности — будь то в программировании или в других областях. Ни в одной отрасли техники невозможно предсказать время и суммы, необходимые для разработки новых вещей. Мы можем предсказывать производство, но производство имеет циклический характер по самому своему определению, в производстве есть процесс обучения, и, если следовать ему, как мы знаем, можно добиться того, что последний экземпляр окажется дешевле первого. Создавая объемистую книгу, посвященную изучению живых организмов и организаций, Дж. Г. Милер в «Живых системах» цитировал исследования Джоан Вудворд, проводившиеся в Англии, и сразу комментировал их.

Еще одним исследователем, распознавшим важность производственник процессов, оказалась Вудворд. В одном из относительно редких исследований, в которых собирались данные по большому числу организаций, она проанализировала 100 промышленных предприятий Южного Эссекса в Англии… Внутри часто выделяемых категорий «штучного», «серийного» и «массового» производств Вудворд провела дальнейшее деление на 11 типов производственных подсистем. «Цельной продукцией она называет такую продукцию, которая производится как отдельная единица — поодиночке, сериями или массовым производством». «Объемная продукция измеряется с помощью веса или объема, к ней относятся химикаты, жидкости и газы».

В своей книге Вудворт комментирует различные виды процессов, сводка которых дана на рис. 6.8.

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

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

«Эффект заброшенных функций» при разработке больших программ

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

Здесь мы сталкиваемся с явлением под названием «заброшенные функции». Необходимо выработать некоторый приблизительно определенный набор функций. По мере приближения срока сдачи работ руководитель разработки начинает понимать, что реализовать все обещанные функции в срок нельзя. Как воздушный шар, теряющий высоту, группа разработчиков избавляется от балласта «необязательных» функций. График «выдерживается», работа завершается «успешно», несмотря на то что в потайной комнате несколько расторопных людей поспешно подключаются к работе, которую должна была бы выполнять вычислительная машина. Теперь все заботы по подключению к системе этих заброшенных функций ложатся на плечи членов группы продолжающейся разработки. Поскольку фаза разработки, построенная по методу «большого взрыва» заканчивается, все оставшиеся недоработки маскируются под названием «сопровождение». Число занятых в этой работе людей обычно значительно уменьшается; группа «сопровождения» по сути является группой разработки (см. рис. 6.9)

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

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

Функции, «заброшенные» в целях выполнения графика, продолжают реализовывать. (Рис. 6.10.) Этим занимается группа операций и сопровождения на собственные средства, поскольку никто не горит желанием признать реальное положение дел. Это нежелательно, но так случается в жизни.

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

«Мы восходим на небеса по руинам наших самых сокровенных надежд, обнаруживая в конце концов, что наши неудачи были на самом деле нашими победами». Эмос Элкотт.

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

Планирование развития

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

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

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

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

4. Нам следует использовать табличные методы управления логикой работы программы. Изменяя строку таблицы, вы меняете алгоритм. Мы использовали этот метод в системе диспетчерского контроля авиалиний. Структура авиалиний определялась таблицами, что избавляло нас от необходимости изменять алгоритмы программ, работавших в разных центрах (всего был 21 центр). Таким образом, у нас была одна программа и 21 таблица для 21 центра.

5. Необходимо устанавливать стандарты программирования и настаивать на их выполнении. Стандарты не пользуются популярностью, но необходимы.

6. Следует организовать строгий и детальный контроль. Мы затронем этот вопрос в разделе, посвященном руководству проектом.

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

8. Для обеспечения сопровождения программ нужно заранее планировать сохранение средств тестирования и разработки.

9. Все это необходимо предусмотреть при составлении бюджета.

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

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

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

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

Занятость

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

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

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

Эволюционный подход к разработке больших систем

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

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

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

Вероятно, именно в этом заключается наиболее значительное отличие систем запуска человека в космос (NASA) и диспетчерского контроля авиалиний (FAA) от огромного множества других больших систем. И NASA, и FAA планировали и финансировали сохранность группы разработки на период до 10 лет! Обе организации понимали, что их системы будут развиваться в течение столь длительного времени.

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

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

Случилось так, что буквально на следующий день после этого я встретился со своей хьюстонской группой и узнал, что у них была «версия 14.7» — т. е. всего, если отвлечься от непонятных обозначений с десятичными дробями, было по крайней мере четырнадцать версий, — и все-таки человек высадился на Луну!

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

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

Что мы имеем — или должны иметь — (с точки зрения программного обеспечения) в первой версии программной системы, состоящей из двух весьма различающихся множеств программ, которые будут выполняться одновременно:

1. Множество системных программ, которые будут составлять график выполнения прикладных программ на машине и управлять внешним окружением.

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

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

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

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

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

Задачи руководства программным обеспечением проекта

Руководство разработкой программного обеспечения весьма непростое дело. Нужно решать и управлять решением огромного количества мелких, но и важных задач. Ниже следует список, представляющий собой оглавление «Военного стандарта ВМФ США 1679» — разработку программного обеспечения систем вооружения. Все основные пункты мы уже рассмотрели, но и более мелкие могут играть важную роль и сейчас, и в дальнейшем. Этот список прекрасно иллюстрирует трудности задачи разработки:

Общие требования

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

Требования к проектированию

Формирование программ

Гарантия качества

Руководство конфигурацией

Управление подрядными работами

Отклонения и отказы от требований

Подробные требования

Требования к производительности программ

Вспомогательная информация для требований о производительности программ

Анализ производительности программ для вычислительных машин

Области применения

Функции

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

Описание системы вооружения

Функциональное описание

Подробные функциональные требования

Регулируемые параметры

Системные ресурсы

Требования к проектированию программ

Вспомогательная информация для требований к проектированию программ

Анализ проекта программ для вычислительных машин

Документация, необходимая для требований к проектированию программ

Распределение функций

Функциональная схема программы

Распределение ресурсов и резервы

Проектные ограничения

Проектирование базы данных

Межсистемные взаимодействия

Стандарты программирования

Управляющие структуры

Вставляемые/копируемые сегменты

Структура входов-выходов

Отслеживание связей в программах

Самомодифицируемость

Рекурсивные программы

Размер

Ветвления

Перемещаемость

Формат текста программ

Соглашения, принятые при программировании

Символическая параметризация

Система именования

Численные соглашения

Символические константы и переменные

Выражения из разнотипных операндов

Группирование

Значащие цифры

Структурированные словесные описания

Резюме

Комментарии и примечания в программах

Формат входных записей

Эффективность выполнения

Включения/копирования сегментов на исходном языке

Операторы входного языка

Блок-схемы

Производство программ

Организация производства программ

Руководство ресурсами

Язык

Использование библиотек и управление ими

Последовательная нумерация

Распечатки

Распечатки программ

Распечатки перекрестных ссылок

Карты загрузки

Регенерация программ

Выполнение программ

Анализ выполнения программ

Нефункциональное выполнение

Функциональное выполнение

Тесты программ

Тесты модулей

Тесты подпрограмм

Тесты производительности программ

Комплексный тест систем(ы)

Отчетность об ошибках в программном обеспечении

Категория отчетов об ошибках в программном обеспечении

Приоритет отчетов об ошибках в программном обеспечении

Рассылка отчетов об ошибках в программном обеспечении

Гарантия качества

Обеспечение гарантируемого качества

Уровни отчетности

Участие в обсуждениях

Пересмотр планов

Проектирование программ

Кодирование программ

Тесты

Представляемые элементы

Отчетность

Авторство

Приемлемость программ

Дополнительные требования к приемлемости программ

Требования к тестам качества программного обеспечения для проверки приемлемости программ

Окружение тестирования

Тестируемое программное обеспечение

Документация тестов качества программного обеспечения

Выполнение тестов качества программного обеспечения

Продолжительность тестирования качества программного обеспечения

Входные данные для тестов качества программного обеспечения

Тестирование качества тестирования качества программного обеспечения

Возможность сокращенного тестирования качества программного обеспечения

Тесты качества программного обеспечения и вспомогательные программы сопровождения

Ошибки во время тестирования

Ограничения на тесты качества программного обеспечения

Ограничения из-за ошибок

Временные ограничения

Руководство конфигурацией

Идентификация конфигурации

Основные варианты

Определение документации

Управление конфигурацией

Изменения в программном обеспечении

Изменения в документации

Панели управления конфигурацией программного обеспечения

Вычисление статуса конфигурации

Руководящий контроль

Организация руководства

Требования к ресурсам

Обзоры положения дел

Предметы обзоров положения дел

Пункты, по которым проводятся обзоры положения дел

Обзоры документации

Специальные обзоры

Инспекции и прослушивания

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

Результаты процесса разработки

Что же мы получаем в результате процесса разработки программного обеспечения? Основные результаты таковы:

1. Конечно же, программы, которые будут выполняться, ну а что же еще?

2. Руководства для пользователей. Инструкции и описания, которые сделают систему понятной для пользователя и помогут работать с ней.

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

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

План разработки или проекта

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

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

1) спецификации требований;

2) рабочую схему организационной структуры с указанием сроков реализации;

3) схему расстановки кадров;

4) бюджет;

5) документирование рабочих стандартов. Руководитель разработки поочередно обращается то к плану, то к результатам его воплощения, модифицирует план и опять начинает этот цикл сначала. Рис. 6.15 выглядит просто, но следовать предложенной на нем схеме очень трудно. Самое важное место на схеме отводится пересмотру графика, бюджета или функций (см. маленький прямоугольник слева). Когда дела идут скверно, чем-то приходится поступиться — и этим должно быть что-то из этой тройки. Руководство обычно медленно соглашается с изменениями плана

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

Производительность труда и оценки

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

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

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

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

Более полезным оказывается способ измерения, связанный с подсчетом числа команд или строк текста программы (СТП). Используя это понятие, мы, например, говорим, что данная работа или функция — скажем, составление платежной ведомости — требует 50 тыс. строк программы.

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

Программист А Программист В
Время 2 мес 1 мес
Строки текста 2000 900
Производительность труда 100 °CТП/чел. — мес 90 °CТП/чел. — Мес

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

База данных по производительности труда

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

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

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

Мы решили, что начнем измерять строки программ. У нас уже были, в наших отчетах по контракту, записи о часах работы каждого члена группы, времени, использованном на каждую работу, о категориях всех наших сотрудников (руководитель, аналитик, программист и т. д.) и об их заработной плате. У нас были сведения обо всем — так мы думали. И почти сразу же мы обнаружили, что никто из нас не имел точного определения «строки программы»! А также и «человеко-месяца»!

Определения терминов «строка программы» и «человеко-месяц»

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

Два значения термина «строка программы»

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

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

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

Итак, термин «строка программы» имеет два значения, причем полезными оказываются оба значения:

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

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

Даже получив эти определения, нельзя выйти из тупика.

Определение строки текста исходной программы. Строка текста программы — это любая входная запись длиной до 80 символов (выполняемая и невыполняемая), написанная программистом или используемая в нашей системе программного обеспечения во время его работы. Имеется по крайней мере два типа таких операторов. К одному типу относятся операторы, не предназначенные для переноса в рабочую программу, к которым относятся операторы, написанные, отлаженные, использованные и исключенные (возможные примеры исключаемых операторов: некоторые программы имитации, некоторые моделирующие программы, некоторые тестовые программы), не выполняемые во время использования программы. К этому же типу относятся примечания и описания данных. К другому типу относятся операторы, из которых формируется рабочая программа и которые используются в момент работы программы.

Если мы не будем включать в наши подсчеты строки с примечаниями, программисты, пытаясь повысить свою продуктивность, перестанут писать примечания к своим программам. Это будет неправильно; примечания нужны нам для того, чтобы облегчить проведение работ в фазе сопровождения проекта. С другой стороны, мы не хотим, чтобы программисты писали по две страницы примечаний к программам из 30 операторов. Для написания примечаний должны быть установлены некоторые нормы. Но включать примечания в подсчеты числа строк нужно.

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

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

Категории программного обеспечения

Необходимо различать некоторые типы программного обеспечения, разработка которого проводится нами:

1) операционное обеспечение — как системное, так и прикладное, лишь бы оно использовалось во время работы системы;

2) инструментальное обеспечение — программное обеспечение разработки; программное обеспечение тестирования.

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

1) программного обеспечения фазы использования или операционного программного обеспечения;

2) сопровождения разработки операционного программного обеспечения, включая и «выброшенные программы», например управляющие программы;

3) сопровождения разработки аппаратуры, включаемой в систему;

4) проведения тестирования системы;

5) сопровождения проектирования, например моделирующие программы;

6) руководящего контроля, например PERT, подсчета стоимости.

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

Определение человеко-месяца

В подсчеты с помощью человеко-месяцев (ЧМ) включаются все участники, поддерживающие разработку программного обеспечения от начала работы над проектом и до выпуска в свет готовой системы. Работники, проводившие анализ требований, проектировщики, секретари, руководители, библиотекари, охрана — все они должны учитываться (пропорционально вкладу в создание программного обеспечения) при подсчетах в человеко-месяцах. Некоторый процент от человеко-месяцев, отнесенных к инженерной части, должен быть подсчитан как вклад в программное обеспечение, точная доля определяется совместно руководством технической частью проекта и разработкой программного обеспечения. Необходимо учесть все часы, занятые работой над проектом, от самого начала до самого конца.

Изменчивость

Не следует думать, что отношение СТП/ЧМ остается постоянным для разных типов программного обеспечения. Создавать тексты для использования в фазе разработки легче, чем для использования на стадии реальной работы. Управляющее, или системное, программное обеспечение (операционное) должно, видимо, быть более сложным, чем прикладное (операционное) обеспечение. Первые варианты могут оказываться более сложными, чем более поздние, так как постепенно приходит опыт, и группы программного обеспечения начинают более эффективно работать именно как группы.

Вопросник по производительности труда

Обратимся теперь к данным, собранным нами в базе данных по производительности труда. Мы хотели выяснить, что же влияет на производительность труда, измеряемую в строках программы, а для этого нам нужно было собирать множество различных данных о проводимой работе. Нам было необходимо знать окружение, в котором работает заказчик. Есть ли у заказчика достаточный опыт для работы в данной прикладной области? Имеется ли у заказчика достаточный опыт в области обработки данных или хотя бы вообще по автоматизации? Участвовал ли заказчик в составлении проекта? В определении требований? В разработке программ? Было ли взаимодействие с заказчиком очень сложным или его можно отнести к средней сложности?

Мы хотели знать «цену проекта», его оцениваемую стоимость. Не требовали ли от нас больше разных переездов, чем это вызывалось необходимостью? Находилась ли группа в непосредственной близости от заказчика? Было ли место расположения разработчиков «хорошим»? Или плохим? (В одной крупной разработке нам приходилось возить программистов по утрам за 50 миль, а по вечерам привозить, их обратно, для того чтобы они смогли получить доступ к машине, на которой проводилась разработка, и вступать в контакты с заказчиком.) Не было ли так, что машинное время выделялось только с полуночи до 4 ч утра?

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

Был ли составлен план, использовался ли он для:

— оценки изменений в проекте системы и внесения этих изменений

— оценки изменений в проекте программного обеспечения: и их внесения

— тестирования (на всех уровнях)

— извещений об ошибках в программах, выявленных и исправленных

— использования вычислительных машин

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

— защиты важнейшей информации

— контроля денежных затрат

— руководящего контроля

— документирования

— стандартизации методов кодирования

Не использовались ли необычные устройства ввода/вывода или средства отображения? Не было ли это оборудование использовано каким-либо необычным образом? Работала ли программистская группа на данной машине прежде? На этом же языке? С приложениями таких же размеров и сложности? Работали ли ведущие программисты прежде того в совместных проектах? Каково было окружение разработки? Работа велась с выделением пультового времени? Или в режиме разделения времени? Использовались ли удаленные терминалы? Привлекались ли программисты к непосредственной работе на машине? Каким было время ожидания решения? Применялся ли диалоговый режим? Как долго? Менее 2 ч, от 2 до 7 ч, от 8 до 24 ч, более 24 ч? Какая доля программ разрабатывалась с использованием:

— библиотеки инструментальных программ,

— программного библиотекаря,

— структурного программирования,

— сквозного контроля,

— программирования сверху вниз,

— метода главного программиста?

После этого мы приступили к оценкам сложности:

— приложений,

— алгоритма программ,

— межпрограммных связей,

— внешних связей,

— структуры базы данных.

Какая доля программ пришлась на:

— нематематические приложения и форматирование ввода/вывода,

— математические и вычислительные программы,

— программы управления центральным процессором и вводом/выводом,

— программы возвратов и восстановления после сбоев?

Какие ограничения повлияли на проект:

— в оперативной памяти,

— временные,

— возможностей ввода/вывода?

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

— управлении,

— администрации,

— программировании,

— анализе,

— технических работах.

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

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

Ошибки при подсчете СТП

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

Многие люди, измеряя человеко-месяцы, ошибочно подсчитывают только время, затраченное программистами. Мы уже видели, что в очень больших проектах более 50 % всех усилий предпринимается группами сопровождения и управления. Это тоже прямые затраты, их также необходимо учитывать.

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

Как-то у нас был контракт на западном берегу, в котором мы недооценили объем программ примерно вдвое. Мы сменили руководителя — и новый не хотел отвечать за чужие грехи. Спорить с этим было трудно.

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

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

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

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

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

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

Неверная интерпретация содержимого базы данных. В начале 1977 года я допустил публикацию одной статьи в журнале IBM System Journal, написанную Уолстоном и Феликсом с условием, что будет опубликована только часть данных и что будет ясно указано, что приводимый анализ является предварительным. И тем не менее статью часто цитируют, как будто это окончательный отчет, и это цитирование не всегда верно.

В статье утверждалось следующее:

Данные были собраны по шестидесяти завершенным разработкам программного обеспечения. Использовалось двадцать восемь разных языков программирования. 28 языков для 66 различных вычислительных машин. Размеры программ изменялись в диапазоне от 4000 строк исходного текста до 467 000.

Рабочие программы в статье не рассматриваются; сведения касаются только исходных программ. В статье приводится список 29 переменных из 69 представленных в отчетах, отбирались переменные, в наибольшей степени влияющие на производительность труда. В статье полностью игнорировались взаимодействия между этими 29 переменными. Там говорилось, что «анализ переменных проводился независимо друг от друга, возможность корреляции переменных и эффекты этого взаимодействия во внимание не принимались». Таблица 3, приведенная в статье, имела такую первую строчку:

Медиана 50 % Квартили 25–75 %
Строки исходной программы за один человеко-месяц 274 150–440

Теперь мне хочется дать свои комментарии по поводу этой статьи. Рассмотрено менее одного завершенного проекта в расчете на одну вычислительную машину. Каждый из рассмотренных языков применялся в 2.1 проекте. Различия в масштабах были даже большими, чем от 4000 до 467 000 строк. Космические проекты Хьюстона были разделены на несколько «программ», каждая из которых имела отдельный отчет. Но работать по отдельности они не могли.

В одной таблице были сведены средние (медианные) значения отношения числа строк к человеко-месяцам; таблица, показывавшая 29 наиболее важных переменных, содержала именно средние значения. В табл. 3, приведенной выше, отбрасывались верхние и нижние 25 % значений. Все это делало данные гораздо более регулярно выглядящими, чем это есть на самом деле. Цифры, собранные на стр.291 в графе оценок производительности, показывают невероятно широкий диапазон производительности, это осталось для нас непонятным.

В статье не рассматриваются рабочие программы. Но именно они являются результатом работы, а не исходные программы. В базе данных есть сведения по рабочим программам. Игнорировать рабочие программы, значит также игнорировать коэффициент повышения производительности, вносимый языками высокого уровня. Язык программирования не вошел в 29 наиболее важных факторов. Но так дело обстоит только в статье, а не в реальной жизни. Кстати говоря, среди того, что особенно поразило нас после того, как мы впервые просмотрели базу данных, была доля программных проектов, в которых все еще использовались ассемблеры. Таких было более 50 %.

Многие из рассматривавшихся 60 проектов были повторными реализациями, проводившимися теми же группами.

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

В статье предполагается, если не прямо утверждается, что фактором, влияющим на производительность в наибольшей степени, является «сложность взаимодействия с заказчиком». Таблица содержит строку с таким заголовком и некоторые числа; никаких комментариев в тексте нет. Известно, что учитывались отчеты, поступившие с разных концов света. База данных составлялась в Гейтсбурге, шт. Мэриленд, — крупнейшие разработки проводились в Хьюстоне, шт. Техас; Атлантик-Сити, шт. Нью-Джерси; Лос-Анджелесе, шт. Калифорния; а также в Моррис-Плейне, шт. Нью-Джерси. Мы решили, что оценить фактор взаимодействия с заказчиком иначе, как заявив, что он выше «нормальной сложности», невозможно. Нам не удавалось сравнить мнения руководителей из Техаса с мнением руководства в Лос-Анджелесе или в Сайгоне, или в Токио. Их мнения были чересчур личными.

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

Я видел три документа — книгу, авторский экземпляр и статью, в которых данная статья цитировалась неверно! В этих документах утверждалось, что «фирма IBM говорит то-то и то-то». IBM никогда этого не говорила.

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

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

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

Хорошей базы данных, из которой можно было бы извлекать достоверные сведения, в настоящее время не существует. Данные, имеющиеся в нашем распоряжении, поразительнейшим образом отличаются по уровню достигнутой производительности труда, а почему это так, мы не понимаем. Уровни производительности труда в рамках одной и той же работы могут доходить от 100 °СТП за человеко-месяц до 6 °СТП за человеко-месяц. Мы до сих пор не понимаем причины таких расхождений.

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

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

Множество чисел, интерпретируемых как чисто случайные.

Рис. 6.18 заимствован из исследования Правительства США, посвященного изучению соотношения числа строк сдаваемой исходной программы (ЧССИП) и производительности (СТП/ЧМ). Заметьте, что по обеим осям разметка нанесена в логарифмическом масштабе. Единственное, что показывают эти данные, это, что никаких полезных оценок на их основании сделать нельзя. Разнообразие их просто поразительно.

Рисунок полезен только тем, что показывает отсутствие у нас достаточного количества данных. На этом графике для программ размером в 100 00 °СТП внутрь области, ограниченной линиями, проведенными на уровне отклонений от — а до +а, попали проекты с коэффициентами и 80 и 800 ЧССИП/ЧМ. Такой разброс не может быть полезным для прогнозирования!

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

Форма отчетности по строкам программ

Желательно, чтобы отчеты по проектам выглядели как-нибудь так:

Название: Программа наведения ракет: с математическим уклоном; загружается с перекрытием; критическая по времени.

Функции: Расчет курса, скорости и всех управляющих сигналов, необходимых для ведения ракеты к точке перехвата другой ракеты.

Не включено в программу: а) Отслеживание всех ракет; делается другой программой.
б) Прием и передача всех сигналов; делается где-то в другом месте.
Всего выполняемых стп — 36 441
в рабочей программе
Написано СТП (выполняемых) ЯВУ 7014
машинный язык 1314
Не написано, но выполняется 8424
Человеко-месяцев (прямой подсчет) 340 человеко-месяцев
Программы [38] , написанные, но не сохраненные (выброшенные) 26 584
8144 Тесты
11 240 имитаторы
3100 моделирование
4100 проч.
Программы [39] , написанные и оставленные, но не выполняемые 50 445 всего
22 814 тестовые программы последней версии
18 416 примечания
1114 моделирование
8101 варианты данных
Время от начала работы до сдачи 18 месяцев
Время первой итерации Составления спецификации требований 4 месяца
Составления проектной документации 8 месяцев

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

Некоторые результаты сбора статистики

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

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

Достигнутая производительность труда
Маленький/легкий [40] (300–900)
1 517
2 615
Средний/легкий * (200–600)
3 199
4 39
5 100
6 286
7 524
8 28
9 109
10 167
11 274
12 1071
Средний/трудный* (100–300)
13 562
14 403
15 128
16 81
17 68
18 400
19 253
20 227
21 250
22 163
23 198
Большой/трудный * (50–150)
24 186
25 68
26 284
27 182
28 229
29 46
30 120

Оценка

Оценка размеров программы

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

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

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

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

Факторы, определяющие трудность разработки

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

(A) Функция, которую надо выполнить

(B) Окружение в фазе использования

(C) Факторы, действующие в фазе разработки

Трудность разработки программ = (А) × (В) × (С)

Таблица 6.2. Трудности разработки

Тип использования
I II III IV V
Функциональные
Функции, которые надо реализовать, количество +
Функции, которые надо реализовать, сложность + +
Функции, которые надо реализовать, ясность +
Взаимодействие людей с системой + + ++
Число различных пользователей системы + + +
Число запусков программы + + +
Число машин, на которых будет выполняться система +
Функции, которые надо реализовать, взаимодействия +
Элементы данных
Ожидаемая частота внесения изменений в систему +
Взаимодействия с другими системами +
Окружение фазы использования
Центральный процессор - + + + +
Ввод/вывод + - +
Основная память - +
Вспомогательная память +
Надежность/доступность + + + +
Реальное время + +
Факторы фазы разработки
Адекватность операционной системы + + + +
Время, выделенное на создание программного обеспечения +
Доступность средств разработки; языки, отладчики и т. д. +
Доступность машин при разработке программного обеспечения +
Знакомство группы, проводящей разработку с аппаратурой
Знакомство группы, проводящей программирование с инструментальным программным обеспечением
Число модулей
Стабильность средств создания программного обеспечения
Стабильность вычислительной машины +
Квалификация пользователя +
Нормальная трудность
Легче -
Труднее +
Намного труднее + +

Схема трудности разработок. Таблицу 6.2 можно использовать как справочник, позволяющий определить, на что нужно обращать внимание, приступая к разработке системы. Расставленные в ней оценки «+», «-» — укажут вам, облегчает ли (-) данный фактор разработку или усложняет (+) ее при переходе от систем типов I и II к системам типов III, IV или V. Если на схеме отмечен знак (-), производительность труда будет повышаться, если стоит знак (+), производительность будет ниже. Сначала рассмотрите схему, а затем приступайте к изучению объяснений по каждому из 27 пунктов.

Функциональные факторы

1. Функции, количество Чем больше функций, тем больше нужно написать программ для их реализации. С ростом размеров программ трудность разработки программного обеспечения возрастает нелинейно.
2. Функции, сложность Программа вычисления коррекции орбиты для полета к Луне в 50 или более раз труднее, чем программа добавления очередного взноса за покупку в месячную кредитную карточку. Управляющие программы логически сложны, а логическая сложность представляет большую проблему, чем сложность научная.
3. Функции, ясность Некоторые функции (вспомните платежные ведомости) ясны и понятны. Другие находятся лишь в головах старых мастеров, и при попытке записать их на бумаге может возникнуть страшная путаница, а ведь без записи нельзя программировать. Особенно трудно работать с системами типа V.
4. Незамкнутый цикл, человек взаимодействует с работающей системой Системы, одним из элементов которых является человек, более сложны, чем какие-либо другие. Информацию для человека надо готовить особым образом; ответы, исходящие от него, надо приспосабливать к обстоятельствам; среди этих ответов может наблюдаться значительное разнообразие; человеку надо давать и дополнительную информацию, причем последовательность запросов нельзя сделать достаточно строгой, чтобы не получилось так, что он откажется от пользования системой.
5. Число различных пользователей программы Разные пользователи по-разному воздействуют и на вычислительную машину и на ее программное обеспечение. Стало аксиомой утверждение, что чем больше пользователей у программы, тем больше ошибок будет в ней обнаружено. Под пользователем понимается не просто отдельная вычислительная установка. Машины и программы для управления ракетами могут располагаться в сотнях различных мест, но способ использования у всех будет один и тот же.
6. Число запусков программы Если программа должна работать постоянно, нам надо позаботиться об эффективности (сколько аппаратуры необходимо для ее выполнения) в фазе использования. Если программа будет выполнена лишь единожды, ее эффективность не должна нас особенно волновать.
7. Число машин, на которых будет выполняться данная программа Если разрабатываемая программа будет выполняться только на одной машине, нам можно несколько меньше обращать внимания на используемые ею машинные ресурсы. Программа для радиолокатора, выполняемая на сотнях вычислительных машин, на сотнях кораблей, должна быть до предела отточена и сжата. Лишние затраты памяти будут умножаться в сотни раз.
8. Функции и их взаимодействия Некоторые сложные задачи весьма слабо взаимодействуют со всеми другими задачами, которые решаются на той же машине; другие же имеют настолько тесные связи, что оказываются буквально переплетенными.
9. Элементы данных Число и размеры элементов данных, их разнообразие, их взаимодействия, их изменчивость, все это может иметь огромное влияние на размер программы и на трудности, возникающие в фазе проектирования. Брукс замечает: «Покажите мне свои данные, и я смогу больше рассказать о вашей программе, чем в том случае, если мне покажут блок-схемы».
10. Ожидаемая частота внесения изменений в программу Если моя программа стабильна, т. е. изменяется не слишком часто, мне можно строить ее совершенна иначе, чем в том случае, когда я ожидаю, что она будет часто подвергаться изменениям.
11. Взаимодействие с другими системами Если наша вычислительная система должна полностью находиться в распоряжении каких-либо других систем, мы должны обязательна программировать так, чтобы учесть все типы возможных прерываний.
ФАКТОРЫ ФАЗЫ ИСПОЛЬЗОВАНИЯ
12. Доступная мощность ЦП Для выполнения задания каждая программа использует ЦП. Некоторые программы используют его более эффективно, чем другие. Когда ресурсы ЦП оказываются недостаточными, программистов просят так провести проектирование программ, чтобы они не просто выполнили задание, но выполнил его с учетом заранее описанных ограничений недостаточных ресурсов ЦП. И программисты пробуют и проверяют свою работу, и пробуют снова и снова. Программы будут работать, но с точки зрения времени программирования, это стоит очень дорого.
13. Доступные пути ввода/вывода Логически эта проблема не отличается от работы в условиях недостатка ресурсов ЦП, но в данном случае наибольшая потребность возникает в числе путей, по которым данные передаются в машину и из нее. Много стараний должны приложить программисты, чтобы передать весь поток данных через небольшое число «портов», имеющихся в машине.
14. Доступная основная память Опять та же проблема, но уже со стороны памяти. Для хранения программ требуется память, а если памяти не хватает, программист должен «подкачивать» программы в основную память для выполнения и затем откачивать их во вспомогательную память. Для этого приходится затрачивать как время, так и опять-таки пространство. Может быть и другой вариант, в котором приходится втискиваться в отведенные рамки, создавая проект, а затем снова пытаются втиснуться в них. В 1946 году фон Нейман написал в одной из своих работ, что память является ключом к производительности. Это верно и в наши дни; скорость работы с памятью и ее объем есть критические величины.
15. Доступная вспомогательная память Еще раз та же самая проблема; на этот раз со стороны вспомогательной памяти.
16. Надежность/Последствия отказов Двухдневный отказ в системе типа I может быть вполне допустимым. Конечно, он причинит неудобства, но катастрофы за собой не повлечет. Однако, ни часовой, ни 10-минутный сбои нельзя допускать ни в системе управления авиалиниями, ни в системе управления полетом космического корабля, ни в системе противоракетной обороны. Если последствия отказов значительны, нельзя пользоваться стандартной операционной системой (распространяемой поставщиками аппаратуры). Та же проблема возникает и в системах реального времени. В этих случаях либо пишут новую операционную систему, либо модифицируют старую.
17. Ограничения реального времени Если печать платежной ведомости длится 2.5 ч. вместо запланированных 2 ч, кого это по-настоящему волнует? Возникает лишь легкая досада. Но, если радиолокатор поворачивается за 6.4 с, вычислительная машина обязана принять от него данные, закончив к этому времени обработку предыдущей порции. Если этого не будет, система переполнится. В системе реального времени стандартная операционная система применяться не может. Сколько разных объектов может отслеживаться одновременно? Сколько заданий необходимо завершить перед тем, как приступать к решению новой задачи? Чем больше возможностей и необходимости такого рода, тем больше приходится создавать системных программ для управления потоком данных и содержания его в порядке. Примеры: системы разделения времени; управляющие и командные системы; системы диспетчеризации воздушного транспорта.
ФАКТОРЫ ФАЗЫ РАЗРАБОТКИ
18. Адекватность операционной системы Производители вычислительных машин обычно выпускают или сдают в аренду, или продают большие операционные системы вместе с аппаратурой, которая помогает распределять и управлять работой различных аппаратных компонентов вычислительной машины Однако эти операционные системы могут не вполне подходить для разработки программного обеспечения.
19. Время, выделенное на создание программного обеспечения Временной график становится доминирующим фактором в большинстве современных систем типа V. Причина кроется в том, что вычислительная машина и ее программное обеспечение обычно представляют собой лишь часть некоторой сложной системы. Спутники, корабли, оружие, ракеты, здания, фирмы — все это может задавать общий темп — а программное обеспечение должно быть готово одновременно с другими частями системы. Обычно график выдерживается — естественно за счет тех функций, которые надо выполнять. Сдается меньший набор функций, чем планировалось заранее, а недостающие вводятся в систему в более поздние сроки.
20. Доступность средств разработки Средства создания программного обеспечения, как и любой другой инструментарий, существенно воздействуют на производительность труда. Перед тем, как новую машину начнут использовать в качестве инструмента, ее тщательно изучают. Богатый набор мощных средств значительно повышает производительность труда.
21. Доступность машин для разработки программ Этот пункт имеет два аспекта. Во-первых, люди, строящие системы, понимают, что без вычислительной машины при разработке программного обеспечения обойтись очень трудно. Когда машины нет, либо она недостаточно мощна, все страшно замедляется. В то же время люди, незнакомые с ситуацией, не понимают того, что вычислительная машина представляет собой основное средство разработки во всем процессе создания программного обеспечения. Машина на стадии разработки используется столь же интенсивно, как и на стадии использования. Ну и конечно же машина необходима для тестирования программного обеспечения.
22. Знакомство группы, проводящей программирование, с аппаратурой Во всех областях человеческой деятельности нужно отводить время на приобретение опыта, это же относится и к программированию. Если наша группа программистов уже работала с данной аппаратурой, значит в прошлом она уже приобрела опыт, и от этой группы можно ожидать работы с большей производительностью труда.
23. Знакомство группы, проводящей программирование, с разработкой программного обеспечения Время на приобретение опыта, которое, как мы видели, нужно для работы с аппаратурой, нужно и для изучения инструментального программного обеспечения.
24. Число модулей Число модулей и связей между ними относится к ряду факторов, значительно влияющих на сложность выполняемой работы. Эта область сходна с пунктом «функции, их взаимодействия», но имеет и отличие от него в том смысле, что число модулей не обязательно связано с числом функций, поскольку количество модулей связано с методикой проектирования программ, а количество функций неотъемлемо от выполняемого задания.
25. Стабильность средств программного обеспечения Если средства создания программного обеспечения подвержены изменениям, этот и без того сложный процесс еще усложняется дополнительными, часто случайными проблемами. Примером может служить транслятор, в котором есть ошибки и который поэтому создает неправильные рабочие программы.
26. Стабильность аппаратуры Если используемая в фазе выполнения вычислительная машина находится в состоянии доводки, программисты часто не могут разобраться, где находится ошибка, в программе или в аппаратуре. Это вносит постоянную путаницу. Это, пожалуй, наихудшая из всех ситуаций, с которыми может столкнуться группа, разрабатывающая программное обеспечение.
27. Квалификация пользователя Пользователь есть настоящий заказчик и важнейшее звено группы разработки. Пользователь, ранее работавший с системой типа V, уже прошедший через весь этот процесс, является наилучшим из всех возможных партнеров разработчиков. Неопытный пользователь может полностью парализовать деятельность прекрасной группы разработчиков, поскольку новоиспеченные пользователи прокладывают себе дорогу к цели урывками.

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

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

1. Масштаб. Количество реализуемых функций.

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

3. Логическая сложность. Число условных переходов в расчете на сто команд.

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

5. Взаимодействия с человеком. Насколько часты и интенсивны взаимодействия с системой.

6. Требования реального времени. Сколь быстро должна быть выполнена нужная функция.

7. Стабильность инструментального программного обеспечения. Достигло ли оно нужного уровня стабильности и зрелости?

8. Стабильность вычислительной машины, на которой будет выполняться система. Достигла ли нужного уровня стабильности вычислительная машина, на которой будет выполняться система.

Это самые главные из 27 факторов, которые мы перечислили выше.

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

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

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

Программа, которой нельзя сбиваться, обойдется мне дороже, чем программа, которая выполняет ту же функцию, но при этом допустимы сбои. На сколько же это обходится дороже? Я оцениваю этот фактор — надежность, — коэффициентом 15. Следовательно, если создание «ненадежной» программы стоит один доллар за строку, то надежная программа будет обходиться по 15 долларов за строку.

Каждому из восьми основных факторов я могу приписать такие коэффициенты:

Масштабность (размер) от 1 до 8
Ясность от 1 до 10
Логическая сложность от 1 до 10
Последствия сбоев от 1 до 15
Взаимодействие с человеком от 1 до 5
Требования реального времени от 1 до 5
Стабильность вспомогательного программного обеспечения от 1 до 10
Стабильность вычислительной машины в фазе использования от 1 до 20

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

Однако в реальной ситуации редко может случиться так, что для каждого фактора будут наиболее неблагоприятные условия. Нужно попробовать оценить относительную трудность каждого из них для конкретной задачи по разработке. На рис. 6.19 приведены мои оценки для пакета программ размером в 10 000 строк для управления ракетой. Эти программы не должны сбиваться, должны обрабатывать данные, поступающие от радиолокатора каждые 4 с, никак не взаимодействовать с пользователем и работать совместно со стабильным вспомогательным программным обеспечением на «вполне стабильной» вычислительной машине. Логическая сложность минимальна, а ясность просто на отличном уровне.

Моя оценка стоимости — 32,5 доллара за строку — была получена суммированием стоимостей, показанных на диаграмме. Я начал с 1 долл. за строку, мне нужно было лишь определить множители.

По моему мнению, коэффициенты надо расставить так:

— множитель для логической сложности отсутствует

— множитель для ясности отсутствует

— множитель для взаимодействия с пользователем отсутствует

— множитель для стабильности вспомогательного программного обеспечения отсутствует

— множитель 5 для размера

— множитель 2,5 для реального времени

— множитель 15 для надежности

— множитель 10 для нестабильности вычислительной машины, применяемой в фазе использования

Все это вместе дает общую оценку в 32,5 доллара за строку. Еще раз повторю, что отдельные факторы должны умножаться на соответствующие коэффициенты, а общая стоимость определяется не перемножением, а суммированием по всем факторам.

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

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

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

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

Как проводить оценки

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

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

Предположения при проведении оценок

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

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

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

Организация усилий по разработке программного обеспечения

Правильное решение организационных вопросов лежит в основе большинства наших изумительных достижений, но в то же время мы очень часто путаемся при выборе наиболее правильной организационной структуры. В классической работе Питера Дракера «Организационные принципы», вышедшей в 1945 г., указывается, что высочайший уровень промышленного производства, достигнутый Соединенными Штатами во время второй мировой войны, основывался не столько на технологических достижениях, сколько на достижениях в области организационной.

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

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

Ключевые моменты больших проектов

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

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

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

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

5. Руководство конфигурацией (РК). Постоянный комитет, в который входят по крайней мере руководитель разработки, руководитель выработкой требований и главный руководитель проектом, должен раз в неделю обсуждать все предполагаемые изменения, результаты тестирования и состояние системы. Это единственный способ быть в курсе всех событий, происходящих при разработке крупной программной системы.

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

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

Среди наиболее часто встречающихся ошибок, которые попадались на моем пути, можно отметить такие:

1. Нет проектировщика. «Проект будет развиваться!»

2. Нет независимой группы тестирования.

3. Нет независимой группы по определению требований.

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

Надзор над разработкой

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

Имеется много способов отслеживания множества дат завершения отдельных работ, которые можно выделить в большом проекте. Хорошо работают схемы, составленные по методике PERT или GANTT, если, конечно, их применяют, но на них приходится тратить и людские и денежные ресурсы. Хорошую помощь при прослеживании всех необходимых подробностей могут оказать вычислительные машины и работающее на них программное обеспечение.

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

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

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

Управление

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

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

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

Экономия усилий

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

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

Управление конфигурацией

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

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

Автоматизированная матрица модулей/функций

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

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

Ключ к успеху — руководитель разработки

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

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

Первое качество, на которое надо обращать внимание при выборе руководителя разработки программного обеспечения, это не его технические возможности и даже не его личный опыт, а его эмоциональная зрелость и «неуступчивый» характер. Хорошие руководители разработкой умеют соразмерять цели с реальностью и могут твердо стоять на своем, говоря «нет» непрерывным требованиям ввести «еще несколько» функций, совсем немного здесь и еще чуть-чуть там. Такое наращивание функций называется «потерей элегантности» и может оказаться фатальным. Они знают, что время, необходимое на выполнение n + 1 тривиальных вещей, вдвое больше времени, необходимого на выполнение n вещей, если n стало уже достаточно большим (возражение Логга на закон Грея). Они знают, что Брукс был прав, когда в книге «Мифический человеко-месяц» написал: «Как получается, что программы опаздывают на год? Это происходит постепенно». Они знают, что требования являются первой линией обороны. Не допускай «врага» к этим позициям, и ты будешь контролировать все события.

Вторым необходимым качеством руководителя является внимательность к деталям. Большинство хороших руководителей разработок программного обеспечения тратят очень много времени на изучение мельчайших подробностей работ. И не напрасно.

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

Затем следует учитывать знание области, в которой будет проходить работа. Затем опыт. Приходилось ли ему ранее участвовать в какой-нибудь столь же крупной разработке? Не забывайте о «принципе Питера». Многие люди, бывшие способными заместителями, никогда не могут стать хорошими руководителями! Разработка программ объемом в миллион строк намного более чем в 10 раз сложнее разработки в сто тысяч строк.

Какие качества нежелательны?

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

Технический опыт

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

Карьера разработчика программного обеспечения

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

1. Трудно сказать, насколько велика данная работа.

2. Вы не можете сказать, какова будет (или даже была) производительность труда ваших людей.

3. Вы не можете указать процент выполненной работы.

4. Трудно сказать, в каком направлении идет работа!

5. Трудно сказать, насколько быстро вы движетесь!

6. Трудно сказать, насколько далеко вы продвинулись! Найдется ли человек, который захочет взять на себя руководство работой при таком спектре нерешенных проблем?

Пять стадий развития всех новых проектов

1. Эйфория.

2. Разочарование.

3. Поиск виновных.

4. Наказание невиновных.

5. Награждение непричастных к делу.

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

Печальная участь первопроходцев

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

Вы будете прекрасно вознаграждены, если преуспеете.

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

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

Почему же это должно быть очевидно? Это не так очевидно, как можно было бы подумать! В 1961 г. комитет, созданный по предписанию президента Джона Ф. Кеннеди для расследования причин воздушной катастрофы над Нью-Йорком, вынес рекомендации по автоматизации управления авиалиниями. Комитет настоял на том, чтобы Федеральное авиационное агентство (FAA) для всех новых систем покупало только «отработанные» вычислительные машины. Это ограничение было наложено потому, что в конце 1950-х г. FAA стала вкладывать деньги в разработку вычислительных машин — и деньги стали уходить в эту область, а не на разработку собственно систем управления авиалиниями.

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

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

Небольшая консультационная компания потеряла 300 000 долларов — доход за несколько лет — при попытке закончить работы по контракту, в которых использовалась машина фирмы IBM «Series 1». Аппаратура была великолепной; а системное и инструментальное программное обеспечение было отработано не до конца. Каждый раз оказывалось, что люди натыкались на какую-нибудь неисследованную проблему. Программное обеспечение было новым! По этой причине фирма IBM не давала по нему никаких гарантий. И контракт был передан IBM.

Будет ли удовлетворен настоящий пользователь?

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

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

Пути 2, 3 и 4 тоже не являются «чистыми». Сколько проектов терпели неудачи из-за того, что проектировщики или программисты решали, что они знают, что надо делать, а люди, стоящие выше на служебной лестнице, несут околесицу? Таких проектов было слишком много! Я видел системы, где программисты знали больше, чем проектировщики, и поэтому строили систему по-своему. Видел системы, где проектировщики «знали» все, что требовалось. Видел и системы, где ни один человек ни разу не поговорил с подлинным, настоящим пользователем. Короче говоря, искажения могут возникать и в точках А или В, и в точках 1, или 2, или 3, или 4, и все они плохо влияют на систему в целом.

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

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

Прослушивания

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

Другими словами, при прослушиваниях часто возникают ошибочные выводы! Те, кого вызывали на прослушивание, заявляли: «Мы знаем больше, чем эти эксперты; они ошибаются». И верно, часто так оно и было. Каким образом руководитель может определить, кто же прав? Не означают ли эти ошибки, возникающие в результате прослушиваний, что сама идея таких прослушиваний неверна?

Прослушивания очень важны

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

Что необходимо выносить на прослушивания — и когда?

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

Что такое «прослушивание»?

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

Кто должен участвовать в прослушиваниях?

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

В чем вред прослушивании?

Прослушивания оказывают разрушительный эффект. Руководитель проектом прямо скажет вам, что за каждый день, который отводится на прослушивание, он должен резервировать 2 дополнительных рабочих дня. Он считает, что такое воздействие слишком велико, чтобы подвергать ему проект. Участвуйте в прослушивании и не соглашайтесь на изменения в графике. Типичный ответ руководителя: «Посмотрим».

Отчеты на прослушиваниях — делайте их устно

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

Первый выход на прослушивание или в группу инвентаризации

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

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

2. По крайней мере первый день целиком посвящайте прослушиванию; отложите выяснения на второй или третий день.

3. Обратите внимание на то, кто представляет прослушиваемых: коммерческий директор или сам руководитель программным обеспечением.

4. Обратите внимание на используемые термины. Используется ли, например, слово «модульность»? «Упрятывание информации»?

5. Требуйте четкого определения каждого термина.

6. Попросите посмотреть текущую схему организации работ и краткие резюме ведущих разработчиков.

7. Попросите посмотреть документацию по стандартам; обратите внимание на даты их изменения.

Кадры и инструментарий

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

После завершения планирования и проектирования необходимо привлечь к работе большое количество людей. Здесь опять нас ждут неприятности. Мир страдает от хронического недостатка разработчиков программного обеспечения. Не надо недооценивать суровости такого положения. Если вы по плану должны выполнить работу в 120 человеко-лет за три года, но не сможете найти больше 20 квалифицированных специалистов, ваши 120 человеко-лет могут потребовать целых 6 лет. Компании по производству программного обеспечения сталкиваются с той же проблемой, поэтому передача кому-нибудь контракта на разработку не гарантирует вас от встречи с этой ситуацией.

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

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

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

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

Купить или сделать

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

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

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

Стандартный пакет имеет и свои достоинства, и свои недостатки. (См. табл. 6.23.) Но, невзирая на некоторые минусы, при малейшем шансе на успех мы должны использовать стандартное обеспечение.

Таблица 6.23 «3а» и «против» стандартных пакетов

Преимущества Недостатки
Доступен сразу же Универсален и, значит, не очень точно подходит
Модифицируется и исправляется поставщиком Тратит некоторые ресурсы ЦП
Позволяет использовать разработчиков программного обеспечения на других работах Не точно соответствует данной прикладной области
Зависит от некоторой посторонней организации

Разрабатывать самим или заказывать на стороне

Если программное обеспечение нужно разрабатывать, должны ли мы делать это сами или можно заказать его на стороне? Посмотрите на табл. 6.4 — в ней перечислены все «за» и «против».

Таблица 6.4. Разрабатывать программное обеспечение самому или заказывать на стороне?

Разработка внутри Заказ на стороне
«За» «Против» «За» «Против»
Улучшается контроль Требует значительных людских ресурсов Сохраняются людские ресурсы Затрудняется процесс сопровождения
Уменьшается стоимость Разработку ведут более квалифицированные и опытные специалисты
Создается готовая группа сопровождения Затрудняется процесс сопровождения

Как заказывать разработку программного обеспечения

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

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

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

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

Присутствует руководитель на устных обсуждениях? Какие именно решения там принимаются? Записывайте все устные предложения. Это обычно заставляет людей быть более аккуратными в своих высказываниях.

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

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

Кто еще входит в руководящую группу вашего заказа? Достаточно ли они свободны для этого? Заняты ли они еще в каких-нибудь проектах? Не приглашают ли их еще в какие-либо проекты? Или им поручается только ваш проект?

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

Какие методы управления используются в данной организации? Знаком ли с ними руководитель работ по программированию? Применяются ли они на практике? Имеются ли реальные примеры применения этих методов?

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

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

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

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

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

Все эти методы я постарался суммировать в табл. 6.5.

Таблица 6.5. Как выбирать подрядчика

1. Необходимо собрать устные и письменные предложения

2. Крайне важна сама форма заключаемого контракта

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

4. Стандарты — есть ли они у подрядчика? Опубликованы? Придерживаются ли их?

5. Достаточно ли людских ресурсов?

6. Назначения на руководящие должности

7. Опыт предыдущих разработок

8. Способность к напряженной работе и резервы

Вид заключаемого контракта

Единственным способом, который может применяться при заключении контракта на разработку крупных систем типов III, IV или V, нужно считать способ, при котором сумма контракта первоначально не фиксируется. Из этого правила может быть одно исключение, о котором будет сказано чуть позднее. Контракт без начальной фиксации суммы практикуется в Соединенных Штатах уже несколько десятилетий как основной вид контрактов на разработку. Он выдержал проверку временем, поскольку оказался выгодным как подрядчику, так и заказчику. Он используется в тех случаях, когда заранее не удается установить все необходимые требования и методику разработки в рамках жестко заданной суммы. Тем единственным исключением, которое может встретиться при заказе разработки систем типов III, IV или V, оказывается случай, когда строится в точности такая же система, какая в настоящее время уже используется на практике. Такое случается, хотя и редко.

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

Что делать, когда все идет прахом

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

Сменить руководителя легко, но это не всегда приводит к хорошим результатам. Это всегда большая неприятность. Новый руководитель часто бывает не лучше прежнего. Бывают, однако, случаи, когда другого выхода нет. Мне приходилось сталкиваться с руководителями, имевшими великолепные послужные списки, которые в результате каких-нибудь жизненных неприятностей тем не менее теряли свои прекрасные качества и не могли работать так же, как раньше. Иногда они просто достигали согласно принципу Питера, своего уровня некомпетентности, так что столь большая работа оказывалась им не по плечу. Удаление руководителя всегда оказывает сильное воздействие на всех остальных сотрудников. «Если это случилось с ним, значит, и со мной может произойти то же самое». Решаться на это нужно в самую последнюю очередь.

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

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

Поиски замены для руководителя

Вероятность того, что проект, в котором заменяется руководитель, провалится, очень велика. Один руководитель в нем уже «поработал»; после этого остались очень серьезные проблемы. Кому захочется влезать в эти неприятные вопросы? Всякий, кто обладает высокой репутацией и блестящим послужным списком, знает, что это рискованно, вряд ли может привести к успеху, вообще полно подводных камней, что это положение чревато 80–100-часовой рабочей неделей, повышенной нервозностью, трениями и явной борьбой в коллективе. Новички могут воспринимать его как возможность составить себе имя, выдвинуться наверх, но ведь они — новички, т. е. люди непроверенные и неиспробованные. В настоящее время существует очень мало хороших, полностью оправдавших доверие руководителей разработкой программного обеспечения. Проблема эта не проста.

Неуправляемый гигант

Огромный, неуправляемый проект подобен глухому омуту, в который бросаются очертя голову! Полный хаос! Сотрудники спят на работе, они почти помешались, стали вспыльчивыми, ссорятся, увольняются с работы — им предстоит прыжок в омут, — но они со всей очевидностью неспособны ничем управлять, кроме самых непосредственных, неотложных дел. Это случается нередко. График выдерживается только благодаря исключению некоторых функций. Это приводит к тому, что операторы должны выполнять большинство этих функций, только основываясь на собственных ощущениях, собственных рассуждениях и предположениях. Но работа движется! Проект объявляется успешно завершенным. А иногда случается так, что проект не работает, его приходится откладывать на год, а то и вовсе закрывать. Многие проекты были закрыты после того, как суммы затрат в них превысили 50 млн. долларов.

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

Стандарты программного обеспечения

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

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

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

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

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

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

Приведенное ниже множество «стандартов» (табл. 6.6) установлено для крупных программных разработок. У каждого правила могут быть свои исключения, но в целом его следует принимать за основу в начале работ. Введены ли они в действие? Опубликованы и им уже начали следовать? Понятны ли они? Изменялись ли? Кем?

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

Таблица 6.6. Методы производства программного обеспечения

1. Программы операционной системы Стандартное разделение программного обеспечение
2. Программы системы управления базой данных
3. Программное обеспечение системы связи
4. Программы ввода/вывода
5. Программы работы с дисплеями
6. Программы информационной системы
7. Использование управления конфигурацией
8. Обеспечение необходимого качества
9. Документация, описывающая функцию программы по подпрограммам
10. Диаграммы, отображающие взаимоотношения оборудования и программ, с обозначением внутренних и внешних потоков данных
11. Языки высокого уровня
12. Использование анализа и оценок необходимых ресурсов (ЦП, память)
13. Использование структурного программирования
14. Размеры модулей небольшие; функциональное разграничение ярко выраженное, обязательное упрятывание информации
15. Список ограничений, возникших при проектировании, и принципов построения проекта
16. Частый сквозной контроль
17. Использование библиотекарей
18. Внесение исправлений в рабочие и исходные программы
19. Использование средств автоматизации сопровождения
20. Проектирование высокой производительности системы
а) функциональной: доля удовлетворенных требований
б) технической: точность, методология, проверка алгоритмов
в) операционной: восстанавливаемость после сбоев
г) удовлетворение временных ограничений на производительность

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

Ничто не дается бесплатно — средства на стандартизацию тратятся с первых же шагов

Из-за того что мы настойчиво придерживаемся стандартов, фаза разработки программного обеспечения может потребовать больше времени и будет стоить немного (а может быть, и значительно) дороже. На фазе использования могут произойти подобные вещи. Мы будем вынуждены тратить время на выполнение дополнительных команд, вставленных нами в программу для обеспечения модульности и лучшей читаемости. Нам потребуется несколько больше памяти. Зачем нам это все надо? Для фазы продолжающейся разработки. В этой фазе мы сэкономим столько, что оправдаем все расходы на предыдущих двух.

Склонность к фантазированию

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

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

Репутацию фирмы-производителя нельзя считать мерой надежности. Сколько пользователей пострадало, когда фирма IBM испортила первую версию системы ОС/360? Системы реального времени для модели 67? Программное обеспечение для Series 1?

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

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

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

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

Сопротивление нововведениям

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

Обычно сама идея введения стандартов на программное обеспечение отвергается руководителем разработки программного обеспечения. Отказ от стандартов обычно сопровождается такими высказываниями: «Я уже делал нечто подобное», или «Мы не нуждаемся в подобных накладных расходах». Такой начальник просто отстал от жизни. Дело здесь осложняется тем, что он все же остается руководителем! Теми или иными средствами он выполняет свою работу. Он стал боссом, лидером, добился успеха, а эти новые методы очень странны, они таят в себе опасность. Они могут лишить его действия некоторой таинственности, которой они раньше обладали. Очень вероятно, что благодаря этим новым методам ему с новой силой придется вести конкурентную борьбу за руководящую должность.

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

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

Рассуждая о значении слов, Шалтай Болтай сказал: «Вопрос в том, кто за это отвечает?» Его слова вполне могли относиться к разработке программного обеспечения — кто за это отвечает? Руководство или подчиненные? Из-за новизны нашей отрасли, малочисленности практических работников ключевые решения часто принимаются подчиненными.

Можно ли разрешить сумасшедшим управлять психиатрической лечебницей? Для внедрения новых проверенных методов необходимо жесткое руководство. Старые методы сопротивляются новым. Эти новые методы пугают всех. Кому нужны эти нововведения? Они еще не проверены. «Начальство в этих вещах не разбирается!» (См. табл. 6.7.)

Таблица 6.7. Естественная борьба между программистами и их руководством

Программисты хотят Руководство хочет
Красоты в программах Высокой производительности программ
«Чистых» решений Понятных решений
Сложности Простоты
Напряженности Легкости использования программного обеспечения
Артистичных решений Легкости модификации программного обеспечения

Изменения дорого обходятся с самого начала

В начале 1970-х годов мы издали приказ, по которому все новые программы, создаваемые с участием 4400 сотрудников Центра федеральных систем фирмы IBM, должны разрабатываться с применением методов структурного программирования. Мы обнаружили, что должны переучить примерно 2600 программистов и их руководителей. Это означало 5200 человеко-недель или 100 человеко-лет напряженных усилий, не считая планирования, затрат на подготовку преподавателей, материальное обеспечение.

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

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

Неискренние заверения. Сегодня никто не станет возражать против структурного программирования. В начале 1970-х годов, как мы уже видели, такие люди были, мы уже сталкивались с ними. Но и теперь многие организации, заявляющие что применяют методы структурного программирования на самом деле этого не делают.

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

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

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

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

Если мы можем точно определить данный термин, как это сделали для структурного программирования Милс, Лингер и Уитт, то может быть этот термин и окажется полезным. В общем случае, все это отдает торгашеским духом, о чем можно только пожалеть — ведь у метода наверняка есть свои достоинства, просто его не надо называть «структурным».

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

Разработка или продолжающаяся разработка как наиболее дорогостоящая фаза

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

Продолжающаяся разработка (сопровождение) может составлять большую часть полной стоимости — до 70 или 80 %. Но может быть и так, что ее доля будет очень небольшой. Такие колебания зависят от нескольких факторов. Наиболее важными среди них оказываются продолжительность срока использования программного обеспечения — 1 год или 20 лет; стабильность внешнего окружения, влияющего на программное обеспечение; а также качество программного обеспечения, достигнутое во время разработки.

Мне не раз демонстрировали схемы, на которых указано, что «70 % затрат на программное обеспечение было сделано при его сопровождении». Это чрезмерное упрощение! Для очень большого числа программных систем это просто неправда.

Одна причина оптимистических оценок

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

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

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

Научные исследования в программном обеспечении

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

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

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

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

Отсутствие методов представления программ

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

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

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

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

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

Разрабатывать программы так же, как и аппаратуру?

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

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

2. Взаимосвязи программного обеспечения неограниченны. Ограничениями аппаратуры являются законы физики. Столько-то объектов могут иметь столько-то взаимосвязей. С программным обеспечением дело обстоит не так.

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

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

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

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

Программное обеспечение неосязаемо. Оно еще более неосязаемо, чем художественные фильмы. Представьте себе такой фильм, состоящий из миллионов отдельных кадров, движущихся на высокой скорости через световой луч и проектируемых на экран. Просмотр пленки, полоски шириной 35 или 70 мм или серии фотографий, не означает просмотра фильма. Оценить художественный фильм можно по конечному результату, а результат — это демонстрация на экране. Еще в большей степени подобные рассуждения применимы к программе или программному обеспечению. Статический просмотр написанных или напечатанных команд, хотя и может принести пользу, но не является конечным результатом программы. Конечным результатом можно считать только работающую программу, а не статические представления.

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

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

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

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

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

Физические ограничения запрещали многие возможные ветви или последовательности. Рояль можно считать аппаратурой, у него имеется 88 клавиш. Ноты — это команды пианисту, следуя которым он производит музыкальные звуки, а число различных сочетаний нот неограниченно. А понятие «правильности» весьма субъективно. То, что приятно одному, режет слух другому. Но все это — музыка.

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

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

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

Таблица 6.8. Различия между аппаратурой и ее обеспечением

Ограниченные связи Неограниченные связи
Аппаратура Обеспечение
Рояль Мелодии, музыка
Словарь Романы, поэмы и т. д.
Пленка и проектор Художественные фильмы
Вычислительная машина Программы

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

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

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

Сходство между аппаратурой и программным обеспечением

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

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