Модифицируемость
Многие программы и не требуется развивать. Многие программы не нужно делать дружественными пользователю. И нам не нужно усложнять разработку таких программ требованиями, выполнение которых необязательно. Но от нашего руководства мы вправе ожидать сознательного отказа от этих требований и четкого обоснования принятого им
Жизнь каждого изделия или инструмента проходит несколько этапов. Все инструменты проходят по крайней мере два этапа — разработку и использование. Некоторые, большая часть, имеет и третью — техническое обслуживание и совершенствование.
Простая деревянная
Существуют и программы типа «зубочистки», которые я пишу, выполняю, получаю удовлетворяющий меня результат и выбрасываю.
Молотки делают из металла. Мы делаем их и используем. Ремонт им не нужен, но пользуемся мы ими неоднократно.
Существуют программы типа «молотка». Их пишут, их доводят до работающего состояния и исполняют очень много раз. Как и молотки, они не требуют никаких модификаций, изменений или исправлений.
Существуют программы типа «небоскреба», которые, как и те здания, в которых мы работаем, требуют некоторого дополнительного сопровождения. Однажды мы обнаруживаем, что в нашем здании забиты не все гвозди и завернуты не все болты, поэтому нам надо внести некоторые коррективы. Большинство программ относится к типу «небоскребов», так как мы часто добавляем к нашим «зданиям» новые «пристройки».
Мы обратились к этим трем примерам постольку, поскольку они дают нам повод поговорить о качестве программного обеспечения Качество зубочисток необходимо только при их использовании. Для программ типа «зубочисток» нам не приходится заботиться о компоновке — до тех пор пока они работают на нас, — нам не нужно думать об их документировании, раз мы собираемся использовать их только однажды, а затем выбросить.
Качество молотка нас заботит больше, поскольку нам приходится использовать его продолжительное время. Не так уж много молотков ломается при первом же ударе, но плохо изготовленный молоток сломается гораздо быстрее, чем молоток, изготовленный из более хорошего материала и более старательно.
Так же обстоит дело и с
Заметьте, однако, что для этих программ мы не предусматриваем этапа модификаций (обслуживания). Поэтому
Обращаясь теперь к программам типа «небоскребов», сразу же заметим, что если нам нужно добавить к небоскребу дополнительные помещения, то для оценки, планирования и выполнения всех работ пригодятся любые сведения о проложенных в здании водопроводных трубах, балках, электрических соединениях, проводах и еще о массе различных вещей. Нам будет нужна не пользовательская документация, а сведения о деталях конструкции, которые могут облегчить нам процесс перестройки.
Единственной причиной, по которой нам необходима документация на нашу программу типа «небоскреба», является то, что нам известно о предстоящих в будущем изменениях, а документация сильно облегчает этот процесс.
Это наиболее интересное утверждение; давайте обсудим его подробнее.
Если сформулировать это утверждение в негативной форме, то оно будет выглядеть так: если мы абсолютно уверены в том, что нам никогда не потребуется ни изменять, ни исправлять работающую для нас программу, то в виде, пригодном для чтения ее человеком, она нам никогда не понадобится.
Если бы мы были обладателями такой программы (а в настоящее время в мире достаточное число таких обладателей), мы бы просто загрузили эту программу в память машины, выполнили бы ее, получили бы результаты и были бы ими довольны.
Конечно, временами мы бы волновались из-за того, что в программе могут быть скрытые дефекты или ошибки, или из-за того, что окружение программы меняется, и нам необходимо либо разбираться в структуре программы, либо писать полностью новую программу. Но, если все эти ужасы минуют нас стороной, пока мы находимся «у руля», мы можем сказать, что абсолютно удовлетворены работой нашей программы. Она выполнила свое дело, а мы этим остались довольны.
В настоящее время большинство программ в мире являются программами типа «небоскреба»; в них есть ошибки и недоработки, они нуждаются в модификации, чтобы не отставать от постоянно меняющегося окружения. Следовательно, как и проектировщикам, людям, проводящим модернизацию, необходимы синьки со схемами и документы, помогающие разобраться в причинах ошибок и исправлять их.
В здании, построенном согласно утвердившейся практике, обязательно должны быть предусмотрены вполне определенные коммуникации. Мы можем на это рассчитывать, а это облегчит нашу задачу перестройки.
Так же обстоит дело и с программным обеспечением. Если программисты и проектировщики исходной версии программы следовали «отработанным правилам», наша задача весьма и весьма облегчается. Даже сильнее, чем в строительстве, поскольку мы имеем дело с неосязаемыми вещами.
Существуют различные способы разделения процесса разработки программного обеспечения на этапы. При некоторых из них выделяют большее количество этапов, при других — меньшее. По-видимому, неизбежными являются шесть этапов.
Разработка программного обеспечения:
Определение требований
Проектирование
Написание команд программы
Компоновка
Тестирование
Документирование
Первый род деятельности, определение требований, представляет особую сложность для больших систем типа V, и вскоре мы его рассмотрим весьма подробно.
Проектирование, имеющееся в виду здесь, есть проектирование именно программ, а не той системы в целом, частью которой являются эти программы. Более глубокое изучение этого процесса мы проведем после того, как рассмотрим определение требований.
Третьим пунктом является написание команд, сведение проекта программного обеспечения или просто программы к последовательности машинных команд. Мы будем называть этот процесс программированием.
Компоновка представляет собой комбинирование, связывание отдельных частей программы, написанных разными людьми или группами, в одну большую систему программного обеспечения. Если в нашем распоряжении находятся 700 программистов, создающие отдельные программы, то задача «объединения» этих программ в одну систему может стать просто огромной, требующей много времени, дорогой и чреватой многими ошибками. Мы в дальнейшем увидим, что для компоновки систем из отдельных заранее написанных программ нужно создавать специальные инструментальные средства.
Тестирование, или, как его сейчас часто называют, верификация, — это весьма важный и сложный род деятельности.
Как мы уже знаем, документация особенно важна на этапе продолжающейся разработки.
Давая поэтапный список процессов как это сделано на рис. 5.2, мы должны понимать, что реально он никогда не бывает таким простым и понятным.
Очевидно, что только простейшие задачи проходят все шаги без каких-либо итераций, т. е. постоянных возвратов на более ранние этапы процесса. При проектировании кто-то может обнаружить, что следование какому-нибудь требованию может привести к двукратному увеличению стоимости разработки подсистемы. Разработчик должен пересмотреть и переоценить требования. Этот процесс продолжается непрерывно. Группе проектировщиков передается новая информация, проект должен быть пересмотрен. (См. рис. 5.3.)
В конце 60-х гг. в Гейтсбурге в отделении фирмы IBM мы создали специальный курс лекций под названием КУПП — курс управления программным проектом. Этот курс был предназначен для того, чтобы молодые руководители работ лучше понимали, на что обращать особое внимание, как привести проект к оптимальному результату (см. рис. 5.4.). Материал мало менялся с годами, я здесь привожу две диаграммы распределения людских ресурсов, использовавшихся на протяжении 5 лет.
Рис. 5.4 был в конце концов признан неправильным. Для больших проектов проектирование не кончается никогда. Диаграмма была изменена таким образом, чтобы отразить продолжающееся в течение всего этапа разработки проектирование (см. рис. 5.5).
Нам никогда бы не пришло в голову, что деятельность по определению требований, как и проектирование, могла бы продолжаться в течение всего хода работ по разработке. Как показано на рисунках, число занятых людей резко уменьшается после сдачи системы. Такого не случается только с системами типа V. Причина заключается в том, что «закон обязательной даты» — необходимость сдать работу в срок, приводит к временному откладыванию реализации многих обещанных и запланированных функций. Их приходится вводить в действие после «сдачи».
Как мы увидим, распределение времени по различным этапам зависит от множества факторов. Однако размер программной системы, зависящий только от того, какие функции она должна выполнять, является одним из основных определяющих факторов. Время, затрачиваемое на написание программ, сокращается по отношению ко времени и усилиям, затраченным на весь проект в целом, по мере увеличения проекта.
Эти ошибочные диаграммы укомплектования персоналом очень живучи. Диаграмма, изображенная на рис. 5.6, появилась в ведущем журнале отрасли в 1979 г.
Рис. 5.7, созданный Э. Ферентино, полнее соответствует реальной ситуации, или, лучше сказать, ситуации, которая должна возникать при разработке крупномасштабного программного обеспечения.
Еще раз взгляните на модель, использованную нами в отделении федеральных систем фирмы IBM в начале 70-х гг. (рис. 5.5). Процесс проектирования, как мы уже видели, отражен вполне удовлетворительно, но совершенно неправильно представлена роль тестирования. Показано, что тестирование начинается только вместе с кодированием.
Как можно видеть из правильной модели, тестирование должно начинаться вскоре после «первого прохода» процесса определения требований.
Первые из приведенных выше диаграмм отражают подход, называемый теорией «большого взрыва». Этот подход строится на предположениях, что разработчики хорошо знакомы со всеми требованиями, что требования не меняются и что можно спроектировать достаточно эффективную систему, удовлетворяющую этим требованиям. Такое, однако, случается только для простых программ типов I и II, причем только небольших и средних размеров.
Для программ типов III, IV и V дело осложняется тем, что разработчик не вполне понимает все требования. Когда
Мы уже отмечали, что к моменту первичной сдачи редко завершаются работы по реализации всех необходимых функций. Недоделки устраняются
Необходимо при этом отметить, что кривая, отмечающая количество используемого персонала, после первичной сдачи не должна сразу же резко снижаться! Это и не происходит в действительности! На самом деле строится несколько версий системы, каждая из которых содержит все больше функций, все меньше ошибок, в более поздних версиях все с большей полнотой отражается опыт пользователя.
Такая практика долгосрочного планирования и финансирования разработок редко применяется в больших организациях. «Социология» приемки новых систем, возможно, в некоторой степени объясняет такое положение, но чаще причиной ошибочного выбора методики большого взрыва является полное отсутствие опыта.
«Социология»? Ну конечно, ведь поддержание на высоком уровне количества занятых людей в течение многих лет ведет к таким затратам, что проект может быть отвергнут. Поэтому и выбирают график вида большого взрыва. Для небольших приложений типов I и II такая схема привлечения персонала работает вполне удовлетворительно. В других условиях использование большого взрыва — это чистейшей воды афера, причем совершенно бессмысленная! (См. рис. 5.8.)
Все, что мы говорили до сих пор, ни в малейшей степени не объясняет те огромные затраты людских ресурсов, которые необходимы для
Для начала обратимся к конечному результату — что представляет собой программа из миллиона команд? Никто никогда такой программы не видел. Если мы напишем на бумаге миллион строк по 4 команды на 1 см, мы получим рулон бумаги длиной в 250 000 см. Это составляет 2,5 км. бумаги.
Чтобы представить себе миллион команд, представим себе лишь отдельные части программы и их взаимоотношения. Способы представления таких программ будут вкратце описаны на с.155.
Для того чтобы поверить в истинные масштабы затрат на разработку, их иногда необходимо просто увидеть. Десяток, а иногда и несколько десятков людей работают, чтобы выработать требования, установить, что же должна делать система!
Первичное проектирование ведется меньшим количеством людей, но зато написание программы, программирование должно выполняться сотнями, а иногда тысячами программистов. И опять не меньше десятка людей требуется для компоновки, а для тестирования необходимо привлечь несколько десятков, а то и сотен людей. Документирование работ также требует не одного десятка людей. (См. рис. 5.9.)
Этот шаг является важнейшим среди всех шести этапов процесса разработки. Он влияет на все остальные этапы. Увы, это наименее изученный и наименее понятный процесс.
Процесс определения требований разбивается по крайней мере на две части. Во-первых, нужно понять, что нужно сделать, а во-вторых, нужно документировать это. Без этой второй части большой проект останется неуправляемым.
Определение требований это проблема системного уровня, которая постепенно спускается на уровень программного обеспечения. Если взглянуть на типичную картину большого проекта по управлению процессами типа V, мы увидим что-то похожее на рис. 5.10.
Требования системного уровня определяют требования для отдельных подсистем. По мере развития работ затраты, возникающие изменения, ограничения, возможные прорывы в подсистемах будут оказывать обратное воздействие на требования системного уровня, делая весь процесс итеративным.
Такие итерации в наибольшей степени отражаются на требованиях к программному обеспечению, поскольку именно оно является последней регулируемой инстанцией, с помощью которой руководство проектом может исправлять всякие несогласованности. Аппаратура — вычислительные машины, радиолокаторы, дисплеи, средства хранения информации, модемы — могут быть исправлены только после нескольких лет напряженного труда. К счастью, программное обеспечение может быть модернизировано в соответствии с новой ситуацией всего за несколько месяцев!
Лос-Анжелесская группа из 500 разработчиков под моим руководством делала систему управления искусственным спутником. Спутник вышел на неправильную, нерегулярную траекторию. Некоторые приборы выполняли не те функции, для которых они были спроектированы, другие же не работали совсем. Ценой огромных усилий мои сотрудники сумели модифицировать программное обеспечение таким образом, чтобы задание все же было выполнено.
И вдруг мы обнаруживаем, что наш заказчик крайне расстроен тем обстоятельством, что нам пришлось выйти из бюджета! Мы терпеливо объясняли ему, что наш перерасход в 3 млн. долларов сэкономил ему несколько лет труда. Кроме того, мы спасли его от необходимости запускать новый спутник, что обошлось бы ему в 50 млн. Нас оправдали, но неохотно!
Программное обеспечение всегда становится последней инстанцией; за его счет исправляют недостатки всех остальных подсистем. Оно получает в наследство чужие промахи и ошибки.
Определение требований для систем типов I и II — достаточно простой процесс, практически всегда он бывает сделан достаточно хорошо. Этого нельзя сказать о больших системах типов III, IV и V. Новизна вычислительной техники комбинируется с трудностью определения требований для больших систем, которые прежде никогда не строились. Люди никогда раньше не применяли автоматизированные системы в этих областях, поэтому они не сразу могут понять все возможности этих новых для них систем.
В дополнение к этой неизвестности действуют еще два фактора. Во-первых, окружение, в котором будет работать система, может измениться еще до того, как система будет введена в действие. Во-вторых, может измениться сама система. Различные ее подсистемы могут оказаться совсем другими, чем предполагалось до ее сдачи.
Таблица 5.3. Изменения в системах реального времени