Программное обеспечение разрабатывают уже больше пятидесяти лет, но до сих пор программы, изобилующие ошибками, остаются нормой, а качественные решения — редчайшим исключением. Разнообразие дефектов поразительно: от проблемы 2000 года до изъянов защиты, не говоря уж о множестве катастрофических программных ошибок. Нам следует обратиться к прошлому и понять, почему до сих пор не существует общих технологий, которые позволили бы всем разработчикам писать надежное программное обеспечение с приемлемыми затратами и в разумное время.
В начале XXI века есть смысл проанализировать прошедшие 50 лет. Первые эксперименты, которые можно отнести к современному программированию, проводились еще во время Второй мировой войны. Но именно 50-е годы стали первым десятилетием развития программирования как отрасли. За этот период, включая начало нового тысячелетия, буквально на наших глазах кардинально изменился круг задач, которые способно решать программное обеспечение, и формы представления таких решений.
В не меньшей степени изменились методы работы и отношение к программированию самих разработчиков. Технологические достижения в аппаратном обеспечении, операционных системах и языках программирования помогли сформировать среду разработки. Однако социальные и экономические факторы сыграли, пожалуй, более важную роль, поскольку именно они определяли, каким образом отрасль адаптировала эти достижения, кто, в конечном итоге, стал их использовать, и как они влияют (если влияют) на возможность создавать качественное программное обеспечение.
Хотя полно описать последние 50 лет в короткой статье нельзя, мы можем кратко изложить суть каждого десятилетия, анализируя теорию и практику разработки программного обеспечения, сосредотачиваясь на принципах и тенденциях, которые сформировали современные методы создания программ. Возможно, изучая решения из прошлого, как успешные, так и неудачные, мы обнаружим путеводную нить, которая позволит найти способ улучшить программные системы в будущем.
1950-1959: возникновение
Программируемые компьютеры впервые начали использовать для решения военных задач, стоявших перед США во Второй мировой войне. Такие устройства требовались для самых разных целей, от вычисления траекторий бомб до дешифровки вражеских радиопередач. Именно война стимулировала создание более качественных и быстрых способов вычислений. К решению этой проблемы были привлечены самые блестящие специалисты. Первыми «компьютерами» были люди, главным образом женщины, которых в 40-х годах не брали в армию США. Они составляли длинные «конвейеры» из механических счетных машин. Представьте себе «работу» программы следующим образом: каждая из сидящих в ряд женщин, работает на своей станции, выполняя определенную часть вычислений траектории бомбы, и передает ответ своей соседке для выполнения следующего шага.
Но в военных условиях скорость и точность одинаково важны, а компьютер ENIAC Дж. Преспера Эккерта и Джона Мочли гарантировал и то, и другое. Кроме того, война открывает финансовые возможности, которых в других условиях может и не представиться. ENIAC был в большей степени электрической, нежели механической машиной, используя электричество не только для управления механическими компонентами, но и для самих вычислений. Эта машина могла не только порождать результаты, но и автоматически использовать эти результаты для других вычислений. Однако ENIAC опоздал, не успев решить ни одной задачи для военных целей (Scott McCartney, ENIAC: The Triumphs and Tragedies of the World?s First Computer, Walker and Company, New York, 1999).
После войны компьютеры стали применяться в первую очередь именно для оборонных задач. Они создавались для решения серьезных математических проблем, и первыми программистами в большинстве своем были люди, которые составляли и выводили уравнения. Физики и математики тщательно разрабатывали алгоритмы. Они готовили подробную и точную документацию, анализировали решения своих коллег и искали математические доказательства. Никогда больше в истории разработки программного обеспечения к решению задачи программирования не подходили столь методично.
Однако по современным меркам, проблемы, которые решали эти талантливые первопроходцы, были относительно простыми. С другой стороны, нельзя сказать, что алгоритмы и математические вычисления были тривиальными. Но в ту эпоху применялись только самые базовые команды и операции. Современных операционных систем с тысячами встроенных функций и служб тогда не существовало.
Таким образом, в 50-е годы сверхталантливые люди решали проблемы, которые они хорошо себе представляли, в несложных программных средах. Другими словами, это было десятилетие умнейших людей, решавших хорошо понятые задачи: залог успеха и прекрасный путь для формирования дисциплины программирования.
1960-1969: выход в свет
К концу 50-х годов компьютеров было довольно мало, а в 60-е программирование становится общедоступным. Университеты начали предлагать учебные программы по новой технологии, и число производителей аппаратного обеспечения быстро росло. Внезапно компьютеры, и посвященные им учебные курсы, стали доступны всем, или, по крайней мере, тем, кто посещал колледж.
В то же время, компьютеры стали значительно эффективнее и функциональнее. Круг проблем, которые они могли решать, серьезно изменился как по уровню, так и по сложности. Языки программирования также становились мощнее и проще в использовании. 60-е годы были периодом феноменального роста компьютерных технологий и задали тон оставшейся части столетия.
Между тем, в эти годы развитие отрасли могло пойти по тупиковому пути. Менее талантливые люди брались за решение более сложных задач. (Действительно, как можно было найти еще более талантливых и более дотошных разработчиков, чем программисты 50-х годов?) Ситуация располагала к катастрофе, но катастрофы не произошло. Программное обеспечение, написанное в 60-х годах, отличается столь же высоким качеством, что и программы, созданные десятилетием раньше.
Этот кажущийся парадокс имеет простое, хотя и неочевидное, объяснение. Программисты в 60-е годы были добросовестными, а качество программ высочайшим... благодаря отсутствию персональных средств компиляции.
Компиляция в 60-е годы была делом не из легких. По большей части компания или университет имели только один огромный компьютер. Компилятор на этом компьютере, во-первых, находился довольно далеко от рабочего места программиста, во-вторых, был настолько загружен, что время работы на нем приходилось резервировать заранее, а, в-третьих, он был крайне восприимчив к ошибкам в синтаксисе и конструкциях языка программирования.
Другими словами, компиляция недостаточно совершенной программы требовала огромных непроизводительных затрат времени и сил, и, в результате, могла потребовать значительных переделок. Представьте, что вам нужно пройти несколько сот метров, неся в руках стопку перфокарт высотой 20 см только для того, чтобы машина выдала обратно эту пачку с сообщением о «несогласовании типов» на 30-й перфокарте. И могло оказаться так, что к компилятору в следующий раз вас допустят только через несколько дней, а то и недель.
Мучительный процесс компиляции заставлял программистов часами просиживать за рабочими столами с карандашом в руках, тщательно проверяя свои программы, обращаться за помощью к коллегам и снова читать, читать и читать свои перфокарты до тех пор, пока не будут исчерпаны все возможные средства их проверки. Никакие меры не казались излишними, поскольку цена небрежности была слишком высока.
1970-1979: хаос
70-е годы оказались далеко не лучшими для поборников качества программного обеспечения. Проблемы 60-х годов — более сложные задачи и менее квалифицированные программисты — в 70-х годах только усугубились. С другой стороны, недоступная и трудоемкая компиляция ушла в прошлое. Появление ПК изменило правила игры, сняв ограничения, которые заставляли добиваться высокого качества программ в 60-е годы.
Настольные вычисления превратили компьютер в инструментарий, действительно доступный для всех, а не только для математиков, университетских ученых и военных. Никому больше не приходилось часами, днями и неделями ждать, пока представится возможность воспользоваться компилятором, поскольку встроенный компилятор имел каждый ПК. Компилятор можно было запустить в любое время, когда программист хотел быстро проверить синтаксис. Зачем, сидя за столом, тщательно анализировать каждую строку, когда можно запустить компилятор?
Возможно подобную «лень» программистов стимулировал тот факт, что изменился и вид задач, для которых создавалось программное обеспечение. Программисты больше не занимались кодированием математических алгоритмов. Они создавали системы, которые позволяли работать быстрее и эффективнее. Они писали программы, о которых раньше не приходилось и мечтать.
Это была эпоха, когда программисты стали выдавать ошибки за особенности программ. Наивные пользователи 70-х с готовностью соглашались на сложные ухищрения для того, чтобы обойти ошибку, если верили в то, что это была «единственная возможность реализовать требуемую функцию». Программисты дошли до того, что стали выдавать ошибки за проблемы конфигурации и операционной среды, спровоцированные самими пользователи. Пользователи же слишком мало понимали, что же на самом деле происходит.
Тестирование стало еще одной потерей этого десятилетия хаоса. В 60-х годах компетентные разработчики сами выполняли весь анализ и тестирование. Но в 70-е, когда начался бум в создании автоматизированных решений для новых задач (и в добавлении новых возможностей к существующим системам), появился большой спрос на программистов. Поэтому каждый, кто хоть что-то знал о программах, стал заниматься программированием, и в этом ажиотаже о тестировании попросту забыли.
Конечно, организации, занимающиеся разработкой программного обеспечения не намеривались вовсе отказываться от тестирования, но многие из них отдали его на откуп неспециалистам, по существу превратив в тестировщиков подсобный персонал. Сейчас тестировщики по-прежнему вынуждены мириться с непрестижностью своей работы, корни которой уходят в те годы.
Код, написанный в 70-х годах, — самое худшее, что есть в современном программировании. Для него даже существует специальное название: «унаследованный код». Он пугает, он запутан, и с ним очень сложно работать. Большинство специалистов стремятся всеми возможными средствами избежать необходимости его поддерживать. В конце концов, чужой код иногда понять очень сложно, и одна ошибка, сделанная в модифицированном коде, может породить непредсказуемые побочные эффекты, вне зависимости от того, насколько тщательно этот код протестирован.
Наконец, еще одним важным новшеством 70-х годов стали метрики — показатели, которые, как предполагалось, должны характеризовать «качественность» кода, но зачастую их интерпретировали слишком субъективно. Десятилетие хаоса оказалось не самым лучшим временем для введения метрик. Эта теория строится на количественных аспектах исходных текстов — числе циклов, ветвлений, условных выражений и т.д. Вместо того, чтобы пытаться определить, является ли данное программное обеспечение функционально корректным, разработчики могли просто подсчитать число элементов в коде, чтобы установить его сложность.
В 70-х годах это было увлекательное занятие, и, возможно, давало многим разработчикам чувство удовлетворенности своим кодом. Однако до сих пор использование метрик остается исключением из правил. Большинство разработчиков игнорируют параметры, понимая, что хорошие программисты могут создать очень хороший код, у которого отдельные метрики окажутся далеко не лучшими, а плохие программисты могут написать плохой код, который по своим метрикам будет просто блестящим. Так что, к сожалению, «репутация» метрик была испорчена, поскольку изначально они не отражали действительность. Хорошие, современные метрики функциональной корректности и сейчас не пользуются доверием из-за ассоциации с метриками сложности кода, которые были предложены в 70-х годах.
В целом об этом хаотическом десятилетии развития программного обеспечения можно сказать, что оно было ориентировано на код, а не на качество. К концу 70-х стало очевидно, что изменения в отрасли просто необходимы. И первая книга по тестированию программного обеспечения (Glenford Myers, The Art of Software Testing, Wiley, 1979) появилась в конце именно этого десятилетия. Это был верный признак надвигающихся перемен.
1980-1989: возрождение
В 80-е годы были предприняты первые попытки вернуть здравый смысл разработке программного обеспечения. Две из них заслуживают особого внимания.
CASE-инструментарий
Первая такая попытка обрела форму средств автоматизации разработки программ, получивших название CASE (computer aided software engineering). Идея CASE состояла в том, что программисты могли бы создавать более качественное программное обеспечение, если бы у них были вспомогательные программные средства. (Каждому мастеру нужны определенные инструменты. Плотнику, к примеру, молотки. Попытайтесь забить гвоздь в доску с помощью ботинка.)
Как и плотники, разработчики программного обеспечения имели свой набор основных, надежных инструментов: редактор, компилятор и отладчик. Подход CASE дал им возможность получить более совершенные инструменты, например, языки четвертого поколения (для них есть даже своя аббревиатура, 4GL). К сожалению, 4GL и большинство других высококачественных инструментальных средств не оправдали возложенные на них надежды. Возьмем, к примеру, Visual Basic. Все согласны, что это полезный, мощный и популярный 4GL-инструментарий, который позволяет увеличить производительность программистов и сократить число потенциальных ошибок. Однако до сих пор самую высокооплачиваемую работу предлагают программистам на Си, а подавляющее большинство крупных прикладных систем по-прежнему пишут на Си (Брайан Керниган, Деннис Ритчи, «Язык программирования Си» — Brian W. Kernighan, Dennis M. Ritchie, The C Programming Language, Prentice-Hall, 1978). По общему признанию, создание инструментария 4GL и CASE было вполне оправданно, но инструментальные средства общего назначения, такие как редакторы, компиляторы и отладчики, остаются главными в обиходе современных разработчиков программного обеспечения, несмотря на огромный интерес к CASE, возникший в начале 80-х.
Еще одна причина того, что этот инструментарий так и не завоевал широкой популярности, заключается в том, что их предназначение как средств, улучшающих качество программ, играет против них. Если инструментарий обещает значительное увеличение качества продукта, должен ли он сам быть высококачественным? Использовали ли его сами разработчики инструментария? Инструментальные средства, изобилующие ошибками, и при этом предназначенные для улучшения качества создаваемых программ, вряд ли понравятся разработчикам. Не менее важны и личные качества человека, который использует такой инструментарий. Утверждение «дурак с инструментом все равно дурак» остается верным и поныне.
Формальные методы
Второе важное решение, предложенное в 80-х годах для создания более качественного кода, связано с использованием формальных методов. Как и в случае с CASE, многие рассматривали формальные методы как панацею (Richard Linger, «Cleanroom Process Model», IEEE Software, vol. 11, no. 2, Mar. 1994). И, как и в случае с CASE, это решение теоретически могло позволить решить проблему, но на практике все оказалось далеко не так.
В чем состояла ценность формальных методов, состоящих из таких методик, как сокрытие информации, структурное программирование и поэтапное улучшение, рассказано во врезке «Крупицы истины в формальных методах». Эти методики, появившиеся и ставшие популярными в 80-х годах, по-прежнему широко применяются современными программистами, что лишний раз подтверждает их успех. Структурное программирование и ориентация на объекты несомненно полезны для создания качественного кода. Они сейчас настолько широко применяются, что являются скорее правилом, нежели исключением.
Однако строгие формальные методы никогда не будут приняты в ведущих компаниях, специализирующихся на разработке программного обеспечения. Некоторые планируют внедрить тот или иной вариант строгих формальных методов (см. David P. Kelly, Robert S. Oshana, «Integrating Cleanroom Software Engineering Methods into an SEI Level 4-5 Program», Crosstalk, Nov. 1996), но подавляющее большинство современных разработчиков считают их узкоспециализированными. Причины — несоответствие затрат и возврата от инвестиций. Формальные методы сложно использовать, они весьма ресурсоемки и часто предполагают, что программист, применяющий их, должен был иметь чуть ли не кандидатскую степень. И что самое главное, как и в 80-х годах, по-прежнему не хватает инструментальных средств, которые могли бы помочь разработчикам в реализации формальных методов.
Тем не менее, десятилетие возрождения принесло ценные идеи, касающиеся увеличения производительности разработчика. Кроме того, ученые, неутомимо создающие формальные методы, дали научному сообществу методики, которые позволяют систематизировать руководство разработкой. К концу 80-х все осознали важность практических методов программирования, и в целом изменилось отношение к требованиям, гарантирующим более высокое качество.
1990-1999: совершенствование
Следующее «решение» проблемы качества программного обеспечения появилось в 90-х годах под названием «совершенствование процесса разработки программ». Основой этого движения была теперь популярная и часто критикуемая модель Capability Maturity Model. Для краткости мы сознательно упростим формулировку основного принципа совершенствования процесса разработки программ: создание программного обеспечения — это задача управления, к которой можно применять соответствующие процедуры управления данными, процессами и практическими методами, с целью создания максимально оптимального решения. Управление разработкой программного обеспечения гарантирует получение более качественного продукта.
Другими словами, поскольку разработчики не могли должным образом управлять своими проектами (что исторически подтверждается весьма низким уровнем качества программного обеспечения), менеджеры должны ввести организационный контроль. Впрочем, даже самые лучшие в мире процессы можно неправильно реализовать (Jeffrey Voas, «Can Clean Pipes Produce Dirty Water?» IEEE Software, vol. 14, no. 4, July 1997).
Несмотря на кажущуюся легкость тона, речь идет об очень серьезных вещах. При всей неоспоримости того факта, что хорошие процессы разработки программного обеспечения, как правило, необходимы, идея совершенствования таких процессов предполагает формирование антагонистических отношений между руководством и техническими специалистами. Ситуацию усугубляет и тот факт, что многие менеджеры, которые ничего не знают о программном обеспечении, внезапно выясняют, что их опыт якобы весьма востребован в программных компаниях, где задача совершенствования процессов разработки ставится во главу угла.
Однако разработка программного обеспечения в основе своей — это техническая задача. Хорошие разработчики могут создать хорошее программное обеспечение, несмотря на плохое руководство или даже его полное отсутствие. Однако обратное неверно: неквалифицированные технические специалисты вряд ли разработают хорошее программное обеспечение даже при блестящем руководстве. Описание другого исследования, но с аналогичными выводами, главным образом относительно роли руководства в решении проблемы 2000 года, можно найти в статье Роберта Гласса (Robert Glass, «Y2K and Other Software Noncrises,» IEEE Software, vol. 17, no. 2, Mar. 2002). В силу вышесказанного, CMM внедряется медленно. Во многих программных компаниях разработчики по-прежнему не знают о ее существовании.
Модель CMM — это не только идея совершенствования процессов разработки, возникшая в 90-х годах. В последние годы этого десятилетия организации, специализирующиеся на разработке программного обеспечения, начали применять ту или иную популярную теорию к своим процессам. Пример тому — Six Sigma, метод первоначально предназначенный для сокращения ошибок при проектировании и производстве аппаратных систем.
«Шесть сигма» (Six Sigma) — это дисциплинарный, определяемый данными подход и методология ликвидации дефектов в любом процессе — от производства до транзакций, от продукта до службы. Чтобы добиться уровня «шести сигма», процесс не должен порождать более 3,4 дефектов на миллион случаев (http://www.isixsigma.com/sixsigma/six_sigma.asp).
Главный недостаток методики Six Sigma, состоит в том, что до сих пор не ясно, что означает миллион потенциальных случаев появления ошибок в программном продукте. Более того, как это вообще их можно корректно подсчитать?
Еще большему увеличению пропасти, разделяющей руководство и технических специалистов в процессе разработки программного обеспечения, способствовало то, что в 90-е годы достигнут значительный прогресс в развитии вычислительной инфраструктуры. Новые операционные платформы превзошли более старые операционные системы по функциональности. Знания, которые раньше были полезными, стали ненужными. Появились новые языки программирования, мгновенно завоевавшие популярность. Программированию приходилось учиться снова и снова. Новые API для коммуникаций, защиты, распределенных вычислений и, конечно, Web, полностью перевернули жизнь разработчиков. Поскольку разработчики постоянно находились в стрессовых условиях, так как были вынуждены без конца изучать все новые и новые технологии, у них не было времени на то, чтобы следовать конкретным стандартам на процесс разработки программного обеспечения.
В защиту идеи процессов разработки программ можно сказать, что это было абсолютно новое явление. Как и многие другие новшества, оно не было до конца понятным, и зачастую его использовали неверно. Нам кажется, что одна из особенностей 90-х годов состоит в том, что практика процесса разработки программ не позволяла с легкостью поддерживать новые технологии. То, что работало на мэйнфреймах или настольных приложениях, не обязательно работает на продуктах, которые быстро создаются и ежечасно развертываются в современном мире, где существует Internet.
Однако как это было и в случае с его удачными предшественниками, особое внимание к процессу разработки программ дало свой положительный эффект. Тот факт, что значительно больше разработчиков узнали о таких простых вещах, как управление конфигурированием, контроль ошибок и анализ с помощью коллег, безусловно, оказалось полезным. 90-е годы начинались как революция процессов, а закончились осознанием того, что процесс разработки нельзя навязать людям, и вряд ли такой подход станет популярным в ближайшие годы. Более того, бессмысленно реализовывать процесс ради самого процесса. Улучшение процессов разработки программ возможно за счет их упрощения, увеличения конструктивности и использования более качественных технических решений.
Наконец, 1990-е годы ознаменовали первую реальную попытку превратить разработку программного обеспечения в инженерную дисциплину с помощью концепций CBSE (component-based software engineering — «компонентная разработка программного обеспечения») и COTS (commercial off-the-shelf — готовые коммерчески доступные компоненты). Идея состоит в создании небольших, высококачественных модулей и последующего их объединения. Проблема, безусловно, заключается в том, что объединенные вместе высококачественные модули не обязательно превратятся в высококачественную систему. Комбинированная система может оказаться никуда негодной из-за некорректного способа объединения, либо из-за ошибочных представлений о поведении компонентов или о среде, в которую они помещаются. Более того, COTS-компоненты, которые обычно лицензируются в виде исполняемых модулей, могут породить неприятные побочные эффекты, неизвестные получателю лицензии. Подобные побочные эффекты иногда проявляются только при объединении одних компонентов с другими, и их практически невозможно обнаружить при тестировании каждого модуля в отдельности. Парадигма «разделяй и властвуй», которая оправдывает себя в случае аппаратных и физических систем, может оказаться губительной для систем логических. Лишь время покажет, как CBSE повлияет на качество программного обеспечения в будущем.
С 2000 по 2009 год: инженерия?
В первые годы нового десятилетия мы гадаем, что нас ждет в будущем. Сможем ли мы именно в этом десятилетии решить проблему качества программного обеспечения? Будет ли это десятилетием, когда разработчики и пользователи начнут воспринимать ошибку в программном обеспечении как нечто исключительное? Или в конце этого десятилетия мы опять станем возлагать на будущее те же надежды, что и в 2000 году: «Все программное обеспечение содержит ошибки, и каждый должен с этим смириться» (Charles C. Mann, «Why Software Is So Bad, and What Is Being Done to Fix It?» MIT Technology Rev., 17 June 2002)?
По словам Леса Хеттона (Les Hatton, «Does OO Sync With How We Think?» IEEE Software, vol. 15, no. 3, May 1998), «отраслевой стандарт на хорошее коммерческое программное обеспечение предусматривает около 6 ошибок на тысячу строк кода при среднем показателе в 30 ошибок». Таким образом, уровень ошибок последние двадцать лет практически не меняется, несмотря на объектно-ориентированную технологию, автоматические отладчики, более качественные средства тестирования и более строгий контроль типов в таких языках, как Java и Ada. Есть ли основание считать, что в этом десятилетии ситуация изменится? Хотя технические трудности растут, но серьезный стимул дает тот факт, что расходы из-за некачественного программного обеспечения также увеличиваются. Согласно данным отчета, опубликованного в 2002 году Национальным институтом по стандартам и технологии, «объем экономических потерь из-за ошибочного программного обеспечения в США достигает миллиардов долларов в год и составляет, по некоторым оценкам, около 1% национального валового внутреннего продукта» (Research Triangle Institute, «The Economic Impacts of Inadequate Infrastructure for Software Testing,» NIST Planning Report 02-3, May 2002).
Некоторые программисты уже отказываются от традиционных методов разработки программного обеспечения (как одномоментных, так и поэтапных) в пользу методов быстрого и экстремального программирования. В своем крайнем проявлении быстрая разработка — это абсолютно неструктурированный, хаотический процесс, который использует специализированные методы и в котором пропускаются многие этапы планирования и проектирования. Хотя быстрая разработка может сократить время выпуска продукции и увеличить скорость, с которой программист создает код, позволит ли такой подход увеличить качество, совершенно не известно.
Вопрос о том, что это десятилетие предложит, разделяет «кризисных специалистов» и тех, кто верит, что человеческая изобретательность и инженерные «ноу-хау» позволят решить проблему качества программного обеспечения. В конце концов, бухгалтеры разобрались с вопросами качества, самолетостроительные компании решили эту проблему, производители электроприборов справились с такой задачей, водопроводчики нашли выход и электрики добились успеха.
Разработчики программного обеспечения, как минимум, столь же талантливы, как и те, кто работает в этих отраслях, поэтому мы уверены, что в будущем появится более качественное программное обеспечение. Мы, как сообщество, сможем решить эту задачу. Фактически, даже Билл Гейтс, по-видимому, осознал необходимость «расколоть этот крепкий орешек», как он назвал проблему качества программного обеспечения в своем письме, разосланном, по некоторым сведениям, всем сотрудникам корпорации 15 января 2002 года.
«Каждые несколько лет я рассылаю письма, в которых рассказываю о наивысшем приоритете для Microsoft. Два года назад это была реализация стратегии .NET. До того было несколько писем о том, насколько важным является Internet для нашего будущего, и каким образом мы можем сделать Internet действительно полезным для людей. За последний год стало ясно, что задача превращения .NET в платформу надежных вычислений (Trustworthy Computing) — важнее, чем любая другая часть нашей работы. Если мы этого не добьемся, люди попросту не захотят (или не смогут) использовать все остальные наши достижения. Надежные вычисления — это самый высокий приоритет для всего, что мы делаем. Мы должны вывести отрасль на абсолютно новый уровень надежности в вычислениях».
Так оно и есть, хотя и не понятно, когда удастся этого добиться. Когда мы получим возможность создавать действительно высококачественное программное обеспечение? Ответ существенно зависит от того, сможем ли мы (и насколько быстро) воплотить в жизнь некоторые идеи, возникшие в прошлых десятилетиях, идеи, описанные в этой статье. Каждое десятилетие формирует важные представления, и, хотя пока панацея так и не была найдена, каждое из десятилетий дает ответ на часть большого вопроса о качестве программного обеспечения.
Главная проблема нашего сообщества состоит в том, что оно, без долгих размышлений, отказывается от многих полезных идей только потому, что ни одна из них не является панацеей. В течение нескольких десятилетий считалось, что даже если технология увеличивает вероятность создания более качественного обеспечения, но при этом не гарантирует создание безупречных программ, она ни на что не годится. Безусловно, это не так. До тех пор, пока как сообщество профессионалов мы не станем всерьез заниматься интеграцией испытанных методик прошлого в новые методологии увеличения качества, используя их для решения тех же задач, что и создаваемое сейчас программное обеспечение, нам придется еще долго ждать появления такой панацеи.
Джеймс Уайттеккер (jw@cs.fit.edu) — профессор факультета информатики Технологического института штата Флорида. Джеффри Воас (voas@cigital.com) — один из основателей и директор по науке компании Cigital.
James A. Whittaker, Jeffrey M. Voas, 50 Years of Software: Key Principles of Quality. IEEE IT Pro, November-December 2002. IEEE Computer Society, 2002, All rights reserved. Reprinted with permission.
Крупицы истины в формальных методах
Формальные методы разработки программного обеспечения не оправдали возложенных на них надежд, однако некоторые технологии, созданные в 80-х годах в рамках реализации формальных методов, остаются эффективными и сейчас.
- Сокрытием информации (information hiding) называют приемы, благодаря которым одни программы маскируют информацию, получаемую из других программ. Программа может скрывать детали реализации, такие как алгоритмы и данные, благодаря чему, в случае, если их необходимо изменить, другие программы, от них зависящие, не придется переписывать. Программы, скрывающие информацию, взаимодействуют друг с другом через общедоступные интерфейсы. Главное достоинство сокрытия информации заключается в увеличении независимости программ друг от друга. (См. David Parnas, "On the Criteria to Be Used in Decomposing Systems into Modules", Comm. ACM, Dec. 1972.)
- Структурным программированием (structured programming) называют стиль программирования, при котором используется ограниченный набор управляющих структур. Управляющие структуры с одним входом и одним выходом наподобие циклов WHILE, утверждений IF и присваиваний упрощают разработку и отладку программ. Управляющие структуры, нарушающие строгий порядок выполнения, такие как GOTO и BREAK, делают программы трудными для понимания и сопровождения. (См. Edsger Dijkstra, "Structured Programming", Software Engineering: Concepts and Techniques, J. Buxton and colleagues, eds., Van Nostrand, Norwell, Mass., 1976.)
- Пошаговая детализация (stepwise refinement) - метод создания программ, предусматривающий, что разработка начинается с описания программы как набора абстракций. На каждом этапе детализации функции уточняются, и так до тех пор, пока не будет создана окончательная программа. (См. Nicholas Wirth, "Program Development by Stepwise Refinement", Comm. ACM, Apr. 1971.)
Capability Maturity Model
Модель Capability Maturity Model, разработанная в Университете Карнеги-Меллон, «описывает принципы и практические решения, определяющие уровень качества процесса разработки программного обеспечения и призвана помочь организациям-производителям усовершенствовать процессы разработки эволюционным путем, превратив их из хаотических процессов в процессы со строгой дисциплиной» (http://www.sei.cmu.edu).
Коротко пять этапов совершенствования CMM можно описать следующим образом.
- Начальный. Процессы разработки программного обеспечения на этом уровне являются случайными узкоспециализированными.
- Повторяемый. Процесс достаточно очевидный, позволяющий организации повторно использовать процедуры из более ранних, успешных проектов.
- Определенный. Организация использует документированный, стандартный процесс управления и конструирования программ во всех своих проектах как по разработке, так и по сопровождению программного обеспечения.
- Управляемый. Организация собирает, анализирует и регулирует детальные количественные параметры качества как самого процесса разработки, так и итоговых продуктов.
- Оптимизирующий. Главное на этом уровне - непрерывный процесс усовершенствования за счет обратной связи, подтвержденной количественными параметрами, и контролируемого внедрения новых идей и технологий.
Подробное описание CMM можно найти на Web-сайте www.sei.cmu.edu и в отчете «Модель Capability Maturity Model для программного обеспечения» (M. Paulk and colleagues, Capability Maturity Model for Software, Version 1.1, tech. report CMU/SEI-93-TR-24, Software Eng. Institute, Pittsburgh, 1993).
Дополнительная литература о качестве программного обеспечения
- Robert Glass, Software Runaways, Prentice-Hall, Upper Saddle River, N.J., 1998.
- Dick Hamlet, "An Essay on Software Testing for Quality Assurance", Annals of Software Eng., vol. 4, 1997.
- B. Marick, "The Tester's Triad: Bug, Product, User", Proc. Software Testing Analysis and Review Conf., Software Quality Eng. Inc., Orlando, Fla., 2000.
- Glenford J. Myers, The Art of Software Testing, John Wiley & Sons, New York, 1979.