Показатели качества программных продуктов

Причины сложности разработки программных систем

Сложности в разработке программных систем обусловлены следующими факторами:

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

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

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

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

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

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

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

3. Адаптируемость — лёгкость расширения системы. Количественно может измеряться как затраты на интеграцию в систему новой пользовательской функции.

4. Удобство сопровождения — простота поиска и устранения ошибок. Определяется такими факторами, как ведение лог-файлов, наличие средств обнаружения ошибок и т.д.

4. Надёжность — отказоустойчивость системы. Количественно выражается в показателях теории надёжности.

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

7. Безопасность — обеспечение факторов информационной безопасности: целостность, конфиденциальность, надёжность.

8. Документированность — количество видов документов и общий объем документации.

Надёжность программных систем

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

Можно выделить два класса ошибок [майерс]:

1. Отказы программы (невозможность получить результат выполнения функции).

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

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

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

Можно выделить две основные причины ошибок:

1. Недопонимание между участниками процесса разработки (как внутри коллектива разработчиков, так и между заказчиком и разработчиками). Сюда, например, можно отнести:

- чтение между строк — исполнитель может неоднозначные моменты понимать по-своему, а отсутствующие моменты додумывать;

- непонимание — невозможность понять, например, из-за недостатка знаний в некоторой области;

- нечёткое выражение мыслей — созданный документ изначально не соответствует замыслу составителя.

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

Четыре подхода к надёжности.

1. Предупреждение ошибок — количество ошибок минимизируют на этапе проектирования и реализации.

2. Обнаружение ошибок — программа во время выполнения способна обнаруживать возникающие ошибки.

3. Исправление ошибок — программа во время выполнения способна исправлять обнаруженные ошибки.

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

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

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

Реализацией информационного резервирования является использование помехозащитного кодирования.

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

Многие современные языки программирования включают средства обработки ошибок. Например, в С++ для этого предназначена конструкция thy — throw — catch.

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

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

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