Ни у кого нет волшебного рецепта, как создать надежное программное обеспечение, способное успешно работать в любых проектах и организациях, — имеется множество тонких вопросов, которые, возможно, никогда не получат универсального ответа.
По своей сложности задача создания надежного программного обеспечения приравнена сегодня к «грандиозным вызовам» (Grand Challenges) в технологиях и обществе наряду с рядом других известных начинаний.
-
Инициатива Grand Challenges in Global Health, начатая летом 2005 года и помогающая финансировать научные исследования по борьбе с болезнями, от которых ежегодно умирают миллионы людей. В рамках этой инициативы предлагаются гранты на сумму свыше 400 млн. долл. для целого спектра инновационных проектов.
-
Запуск в октябре 2004 года первого в мире частного космического корабля SpaceShip-One, предназначенного для полета на высоте свыше 100 км над поверхностью Земли. Годом позже автомобиль Stanley, модель Volkswagen Touareg, модифицированный студентами Стэнфордского университета, проехал почти 130 миль по пустыне без водителя. Им управляли компьютерные программы и датчики (Christian Science Monitor, 12 Jan. 2006).
-
Поставленная в 2001 году Национальным советом США по исследованиям задача исследования того, как изменились основные биогеохимические циклы Земли в результате деятельности человека. Ее решение поможет предсказать влияние этих изменений в местном, региональном и глобальном масштабе и определить, как эти циклы можно привести в более естественное состояние, если это покажется необходимым».
Тринадцать проблем, которые обсуждаются в этой статье, не связаны с политикой, не имеют скандальной известности или возбуждающей привлекательности «грандиозных вызовов», однако я уверен, что для ИТ-специалистов эти проблемы достаточно серьезны, чтобы их можно было считать «грандиозными» сами по себе.
Проблема 1: качество программного обеспечения
О качестве программного обеспечения, как и о красоте, каждый имеет свое представление. В силу этого качество программ зачастую определяют интуитивно, а не формально. Вы оцениваете его, когда видите саму программу. Как же определить понятие качества? Зависит ли оно от стандартов, людей и процессов? Или оно определяется свойствами продукта? Если вы придерживаетесь последнего утверждения, то должны оценивать такие атрибуты качественного программного обеспечения, как: надежность, безопасность, защищенность, тестируемость, возможность поддержки, производительность, готовность, отказоустойчивость, способность к восстановлению и устойчивость. Программную систему, обладающую этими атрибутами, можно было бы считать высококачественной, но добиться этого весьма непросто. Более того, многие из этих атрибутов трудно определить и оценить количественно. Отсюда возникают некоторые сложности, например, известно следующее утверждение: «Корректную программу проще создать, чем узнать, что вы это сделали». Каким бы странным оно ни показалось, но оно верно.
Совет: начните с формулировки основной задачи, например, «качество означает соответствие цели», а затем проанализируйте, что означают термины «соответствие» и «цель».
Проблема 2: отдача от инвестиций
Пусть ваша программная система удовлетворяет всем требованиям и работает бесперебойно. Но если за это вам приходится платить слишком высокую цену (скажем, вы узнали о том, что существует другая система, которая в равной степени удовлетворяет вашим требованиям, но стоит вдвое дешевле), то будете ли вы довольны отдачей от инвестиций (Return On Investment, ROI)?
В чем преимущество надежного программного обеспечения перед менее качественным? Некачественное программное обеспечение позволяет его создателю зарабатывать деньги на поддержке. В моей практике были примеры, когда изначально создавались программы заведомо более низкого, чем было возможно, качества, поскольку доходы от продажи лицензий были настолько малы, что оставалось просто ждать, когда начнут проявляться ошибки.
К счастью, сообщество программной инженерии работает над определением параметров ROI, используя данные эксплуатации, то есть на основе статистики, а не эмоций. Однако взаимосвязь между методами, подходами и моделями применительно к экономике общей стоимости владения по-прежнему четко не определена из-за множества непредусмотренных параметров. Сообщество активно ищет выход из этой ситуации, но универсальные решения появятся лишь через многие годы.
Совет: проблема требует не столько исследований, сколько наблюдения и согласованного документирования проектов, с тем чтобы собрать практические выводы, объединить их и сделать достоянием широкого научного сообщества.
Проблема 3: совершенствование процессов
Может ли из чистых труб течь грязная вода? Может! (J. Voas, IEEE Software, vol. 14, no. 4, 1997). Казалось бы, хорошие процессы разработки программного обеспечения позволяют получать более качественные продукты. В физическом инжиниринге это действительно так, но что касается программной инженерии, то здесь единого мнения пока нет. Поддержка CMM Level 5 не гарантирует высокую надежность программного обеспечения, а только предполагает это. Кроме того, данная ситуация возвращает нас к проблеме 2. Какой уровень качества можно считать достаточным, то есть, в каких случаях можно обойтись более простым (и дешевым) решением?
Целый ряд проблем, связанных с тестированием и проверкой корректности программ, вынуждает сообщество программной инженерии признать, что проще оценить процесс, чем программный продукт. И сообщество чаще предпочитает так и поступать.
Совет: анализируйте различные «за» и «против» на уровне здравого смысла применительно к некой ориентированной на процессы схеме. Если вы видите, что определенная часть стандарта просто вам не подходит, опишите в документах, почему это так, и двигайтесь дальше.
Проблема 4: параметры и измерение
Параметры, характеризующие проект, собираются регулярно, но как их интерпретировать — не ясно. Определить, насколько собранная информация согласуется с истинным состоянием проекта, трудно. Исследователи и практики, занимающиеся определением параметров и измерениями, давно пытаются решить эту проблему. Вот почему информацию о параметрах часто собирают, но затем не используют. Если вы не знаете, что означает данная статистика, что вы будете с ней делать?
Совет: если вы намерены собирать показатели, характеризующие проект, по каким-то иным причинам, нежели те, что имеет в виду ваш шеф, попытайтесь убедить руководство дать вам время для того, чтобы обучить других сотрудников вашей группы или, по крайней мере, учесть уроки, извлеченные из собранных данных, в будущих проектах.
Проблема 5: путаница со стандартами
Каким стандартам нужно следовать? Существует свыше 1000 стандартов программной инженерии. Одни созданы для тестирования, надежности, безопасности, защиты и т. д. а другие обязательны согласно требованиям государства.
В любом случае производители программного обеспечения и организации, которые его покупают, вынуждены соглашаться на эти стандарты, а отсутствие согласованности между различными стандартами программной инженерии порождает еще одну серьезную проблему.
Совет: убедитесь, что стандарт, который вы выбрали, подходит вашей организации. Будет намного лучше, если вы выполните только приемлемые для вас требования различных стандартов, а не будете с религиозным фанатизмом следовать правилам.
Проблема 6: интероперабельность стандартов
Если я ничего не знаю о двух программных компонентах, но мне известно о тех стандартах, которые были использованы для их разработки, могу ли я, оценив лишь интероперабельность стандартов, прогнозировать поведение компонентов после их объединения?
Может быть, проще оценить сочетаемость различных стандартов, чем сочетаемость созданных на их основе компонентов? Нужно иметь в виду, что сделать это сложно, да и прибегают к подобному анализу крайне редко. Почему? Потому что одни стандарты в большей степени ориентированы на системы, а не на компоненты, а другие на процессы, а не на продукты. Попытка прогнозировать возможность сочетания различных продуктов — тем более применительно к какой-то конкретной вертикальной предметной области, такой как медицина, энергетика или транспорт, — чтобы полученный продукт казался заслуживающим доверия, обречена на провал, поскольку оценка будет либо неверна, либо неправильно истолкована, либо просто проигнорирована.
Совет: тот же совет, что и для проблемы 5: выбирайте то, что подходит, а остальное оставьте в стороне.
Проблема 7: унаследованное программное обеспечение
Когда нужно признать, что унаследованная программная система уже не подлежит модернизации? В механическом мире понять, когда изношенное оборудование следует списать, очень просто. Примером того, что сообщество ИТ и программного обеспечения не всегда представляет, сколько еще смогут работать старые системы, стала ситуация с проблемой 2000 года и системами на Коболе. В результате пришлось потратить огромные средства на модернизацию ИТ-инфраструктуры, и некоторых буквально охватила паника.
В данном случае задача состоит в том, чтобы еще перед разработкой постараться понять, какова устойчивость систем, а затем уже создавать парадигмы проектирования с учетом требований поддержки. Важно также уметь определять параметры, которые позволят установить, когда придет время отказаться от этих систем, и знать, какая поддержка жизнедеятельности системы необходима и при какой отдаче от инвестиций.
Еще один миф в мире унаследованного программного обеспечения связан с понятием «размера»: размер ошибки, исправления или кода. Здесь мы все руководствуемся интуицией, и эти понятия действительно чисто интуитивны. Короче говоря, размер не должен иметь значения, если серьезная модификация не касается большей части оставшегося кода. Небольшие модификации могут иметь огромное влияние, если они затрагивают большую часть синтаксиса этого кода. И если со статическим отслеживанием все достаточно ясно, то динамическое применяется не часто по тем же самым причинам, по которым столь трудно реализовать на практике многократное тестирование с различными тестовыми случаями.
И еще один важный момент: представьте, что сам код остается неизменным, а мир вокруг нас меняется. Как бы хорошо ни работала программа, если среда серьезно изменилась, то от нее, возможно, рано или поздно придется отказаться. Таким образом, крайне важно понять разницу между изменяемостью кода и изменяемостью среды.
Совет: прежде, чем начать любой новый проект, обсудите, на какой срок рассчитаны система и среда и сколько денег выделяется для того, чтобы сохранить их работоспособность в течение этого периода времени. Кроме того, готовьте хорошую документацию на само программное обеспечение и его окружение на тот случай, если вы решите не отказываться от системы в те сроки, какие планировались.
Проблема 8: критерий завершения тестирования
Тестирование обходится дорого: отставание по срокам, невозможность найти очевидные ошибки, падение престижа торговой марки и так далее — все это серьезные проблемы. Теоретически можно тестировать до бесконечности и избежать некоторых из этих проблем. Однако здесь возникает вопрос: как решить, когда следует завершить тестирование, каков разумный критерий его прекращения?
То есть задача состоит в том, чтобы разработать такие параметры и модели, которые позволят остановить тестирование не по причине недостатка времени и средств, а опираясь на другие критерии. Эти параметры и модели должны быть научными и математическими. Признайте, что если дело касается критичного к безопасности программного обеспечения, то государственные стандарты определяют, когда следует завершить тестирование, но эти стандарты, как правило, неприменимы к программному обеспечению общего назначения, поскольку выполнение их требований предполагает огромные затраты средств и времени.
Обратите внимание, что тестирование для определения того, когда прекратить тестирование, — не единственное основание для выполнения последнего. Тестирование также имеет другой аспект, в большей степени связанный с тестированием структурных модулей, которое требует своих собственных критериев прекращения. Например, по обязательному требованию полного охвата ветвей или когда человек или инструмент просто не в состоянии создать тестовый случай для того, чтобы охватить какую-то ветвь. Если ветвь действительно недостижима, проблема решена. Если же нет — намерены ли вы сдаться и прекратить тестирование?
Совет: планировать тестирование необходимо параллельно с разработкой и формулированием требований. Убедитесь, что с первого дня в работе группы принимает участие кто-то из отдела тестирования. И постоянно напоминайте о важности этого вида работ, если опасаетесь, что процесс медленно, но верно ведет к тому, что система не будет должным образом протестирована. Будьте настойчивы и укажите, что именно необходимо изменить, чтобы по возможности избежать такого итога.
Проблема 9: интероперабельность и совместимость
Для решения этой проблемы мы должны вернуться к проблеме 1, которая касается определения качества программного обеспечения. Для того чтобы скомпоновать два программных модуля, важно учесть вероятность непредусмотренного поведения. Вопросы, касающиеся всех атрибутов, упомянутых при обсуждении проблемы 1, в том или ином виде возникают при объединении продукта с другими компонентами, которые сохраняют свое индивидуальное непредусмотренное поведение.
При объединении различных компонентов в одну систему необходимо, по крайней мере, для каждого из них в отдельности, учитывать:
-
уникальность версии программного обеспечения;
-
уникальность аппаратного обеспечения, на котором устанавливается компонент;
-
операционную среду;
-
пространство внутренней и внешней угрозы;
-
поддерживаемые политики и процедуры;
-
параметры качества, которые были разработаны для описания поведения;
-
время.
Если попытаться связать эти семь элементов одного компонента с элементами другого компонента (а они могут различаться), вам будет трудно предсказать, как компоненты поведут себя при объединении.
Кроме того, обратите внимание на роль, которую интерфейсы играют в этом объединении. Они могут оказаться столь же ненадежными и так же содержать ошибки, как и объединяемые компоненты. Мы много лет ждали, но придется подождать еще, пока не появится продуманная, масштабируемая теория, позволяющая разрешать неоднозначность таких взаимосвязей. Не хотелось бы возвращаться к временам «спагетти»-логики в интерфейсах.
Совет: проектируйте максимально возможный уровень адаптируемости в компонентах, правда, определенные предположения, касающиеся функциональности, не так-то легко адаптировать. Существуют аспекты, в большей степени определяющиеся внешним миром, чем основной функциональностью, которые позволяют так реализовывать объединение кода компонента с другими, чтобы можно было повторно его использовать с минимальными доработками.
Проблема 10: операционные профили
Проблема в данном случае связана с трудностью определения того, что же представляет собой реальный операционный профиль (Toward a More Reliable Theory of Software Reliability, J. Whittacker, J. Voas, Computer, vol. 33, no. 12, 2000). Большая часть литературы рассматривает эту проблему как вероятность того, что выбран конкретный набор входных данных. В таком подходе нет ничего плохого, но вам по-прежнему придется определять, что собой представляет этот набор.
Программное обеспечение, как правило, имеет множество скрытых пользователей, которые также влияют на его поведение при работе. Задача состоит в том, чтобы определить, кто эти скрытые пользователи, и за счет этого иметь возможность точнее прогнозировать надежность работы и поведение данного программного обеспечения. Любой прогресс в решении этой проблемы будет полезен при создании международного стандарта по сертификации программных продуктов.
И здесь возникает еще один вопрос: на каком этапе жизненного цикла продукта мы определяем свои ожидания по поводу операционного профиля и среды? Например, следует ли сначала зафиксировать ограничения целевой среды, а затем решать, какое программное обеспечение создавать для этой среды, или наоборот? Или есть какое-то промежуточное решение?
Совет: если вы не можете составить представление о некоторых аспектах целевых сред, тогда, скорее всего, вам не удастся создать продукт, который во многих из них сможет работать. Представьте, что вы собирались построить флигель на заднем дворе, а что, если позже выяснится, что там будет жить слон? Вам необходимо совершенно точно представлять себе, какой будет среда, и сразу, как только будет получена информация, высказать свои сомнения.
Проблема 11: проектирование
Эта проблема касается проектирования атрибутов качества программного обеспечения, упомянутых при обсуждении проблемы 1. Эти атрибуты желательны, однако не все достижимы. Одни возникают сами собой, а другие конфликтуют (например, безопасность и производительность). Кроме того, в каждом случае приходится идти на компромисс в отношении затрат, то есть, если вы тратите больше денег на поддержку атрибута X, то у вас остается меньше средств для реализации атрибута Y. Таким образом, одна из самых сложных проблем программной инженерии касается технических и экономических компромиссов при поддержке атрибутов, определяющих качество программного обеспечения. Здесь есть и еще одна трудность. Как с самого начала разработки обеспечить поддержку необходимых атрибутов, и, в частности, реализовать те, которые нельзя определить количественно?
Совет: это проще сказать, чем сделать, но чем раньше вы зададите эти вопросы клиенту, тем раньше он, по крайней мере, задумается о том, что именно для него важнее: готовность или безопасность? Важно ли, что в среднем на восстановление работоспособности системы потребуется два дня?
Проблема 12: сертификация продуктов
В окружающем нас мире с сертификацией физических параметров физических элементов сложностей обычно не возникает. В виртуальном/программном мире сертификация превращается в совсем иную задачу, поскольку непонятно, как сертифицировать нефизические элементы. Они сохраняют наблюдаемые поведенческие параметры, но существенно зависят от среды, в силу чего эти параметры остаются непредсказуемыми и кажутся нестабильными, так что все прогнозы будут сомнительными. Предусмотренные параметры нефизических систем можно оценить статистически, но эта оценка менее ценна, чем динамическая.
Совет: единственный реальный инструмент, который у нас сейчас есть, — это тестирование. Попробуйте тестирование в режимах, отличных от номинального, и тестирование граничных условий. Не существует официальной государственной или коммерческой лаборатории, которая проводила бы настоящую сертификацию продуктов, и поэтому здесь достаточно много зависит от вас самих.
Проблема 13: сервисы
Данная проблема проиллюстрирована на рисунке. Это некое упрощенное представление, показывающее, почему мы так мало доверяем (или совсем не доверяем) программным системам.
Сейчас понятие сервисов становится центральным во всех аспектах нашей жизни. И, хотя мы живем в домах, построенных из кирпича и цемента, мало кто из нас задумывается о том, что они могут рухнуть.
Существует ли специальная формула, позволяющая оценить степень доверия к сервисам? Или к ним применимы все те же идеи, что и к программному обеспечению?
Сама проблема в чем-то напоминает процесс чистки лука, и, поскольку нефизическое решение — это, по существу, сервис, проблема состоит в противопоставлении физического и нефизического. Давайте начнем «чистить этот лук» и посмотрим, что же внутри этой «луковицы». Сердцевина — программное обеспечение версии 1.1, а следующий слой — это аппаратная и системная оболочка.
Для того чтобы программное и аппаратное обеспечение начали работать, необходимы внешние побудительные причины. Итак, у нас есть система, которая работает при неких предположениях, заложенных в программное и аппаратное обеспечение и выбранных из среды. Такой выбор будет, с большей вероятностью, фактором среды, который возникает с определенной количественно оцениваемой частотой.
Однако эта среда может подвергнуться атакам со стороны вредоносных сред. На рисунке это показано на уровне пространства угроз. Заметим, что под угрозой в этом пространстве не всегда понимают вредоносное вмешательство. Это могут быть просто неординарные события, которые возникают не настолько часто, чтобы их можно было поместить на уровень среды.
Продолжая рассматривать нашу луковицу, мы обнаруживаем, что четыре слоя не имеют никакого отношения к таким атрибутам качества сервисов, как надежность, производительность, безопасность, готовность и отказоустойчивость. Более того, это параметры всей системы, которые улучшают или ухудшают ее поведение в целом.
Необходимо также отметить еще один слой — слой политик описывающий, как система должна работать, как к ней получать доступ, как ею управлять и как ее контролировать. Решения на этом слое принимаются высшим руководством — директором информационной службы, генеральным директором, архитекторами систем безопасности и так далее, — которые будут говорить на языке, специфическом для этого слоя. А технические специалисты должны переводить с языка политик на язык атрибутов, потоков, сред, аппаратного и программного обеспечения. Иными словами, существует порядок подчиненности, определяющий путь воздействия, однако далеко не все воздействия из пространства политик должны быть однонаправленными.
Но самая интересная часть проблемы нефизических систем — это не коммуникационные связи между слоями, а время. Время — единственная часть этой модели, которую заморозить не может никто (скорее всего, пространство угроз — вторая после нее по уровню неконтролируемости). На этом рисунке мы видим, что в момент времени t0 у нас есть набор политик (P1), набор атрибутов (A2), среда (E1), которая испытывает воздействие со стороны пространства угроз (T1), и мы живем в мире аппаратного обеспечения (S1) в котором работает программное обеспечение версии 1.1. Однако в момент времени t5 мы имеем набор политик (P2), набор атрибутов (A1), среду (E2), которая испытывает воздействие со стороны пространства угроз (T2), и мы живем в мире аппаратного обеспечения (S2), в котором работает программное обеспечение версии 1.1.
Проблема, показанная на рисунке как ?, заключается в том, что мы хотим знать, что еще изменяется с течением времени внутри конкретного слоя и как это влияет на слои, расположенные выше и ниже. Обратите внимание, что в этой простой иллюстрации я сознательно решил не использовать различные версии программного обеспечения (несмотря на то, что есть версия 1.2).
На этот раз задача состоит в том, чтобы:
-
выяснить зависимости между различными членами одного и того же слоя;
-
определить, как связаны два смежных слоя, и сделать это для всех уровней, вне зависимости от того, смежные они или нет;
-
представить, как априори определить, что ? будет означать для всего предприятия, опираясь на знание меньших ?.
Совет: имейте в виду это представление, если вы постоянно сталкиваетесь с проблемами ? в своей повседневной работе. Это позволит лучше понять, где возникают трудности.
***
С моей точки зрения, перечисленные 13 проблем самые сложные и требуют неотложного внимания со стороны исследователей. Они открывают огромные возможности и определяют план будущих исследований для сообщества программной инженерии. Многие уже работают в этих областях, но реальные результаты появляются крайне медленно. Я умышленно не затрагиваю серьезные проблемы, связанные с безопасностью программного обеспечения, — это отдельная область, а перечисленные 13 проблем в большей степени относятся именно к программной инженерии.
Вывод: более простые проблемы программной инженерии были уже решены за прошедшие годы. Эта статья рассказывает о самых сложных современных проблемах, причем сложность на текущем этапе значительно отличается от той, что была в прошлом. А масштабируемость добавляет еще множество других вопросов, на которых я не стал здесь останавливаться.
Джеффри Воас (jeffrey.m.voas@saic.com) — директор по гарантийному обслуживанию систем в компании SAIC (Science Applications International Corporation) и евангелист SAIC Technical.
Jeffrey Voas. A Baker’s Dozen: 13 Software Engineering Challenges. IEEE IT Pro, March/April 2007. IEEE Computer Society, 2007. All rights reserved. Reprinted with permission.