Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Надежность и диагностика компонентов инфокоммуникационных и информационно-управляющих систем.-1

.pdf
Скачиваний:
0
Добавлен:
20.11.2023
Размер:
3.78 Mб
Скачать

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

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

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

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

191

лагаться в том же порядке. Характеристики терминала и сообщения об ошибках – общие для всех запросов.

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

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

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

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

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

– минимизацией ошибок пользователя;

192

– обнаружением ошибок пользователя, когда они все же возни-

кают;

– минимизацией сложности.

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

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

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

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

4.Обеспечивайте развитые средства помощи.

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

спользователем на его языке, а не на жаргоне программистов.

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

193

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

Основные правила обнаружения ошибок пользователя:

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

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

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

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

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

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

194

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

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

До широкого распространения Delphi и С++ для научных и инженерных вычислений использовался язык ПЛ/1. Он содержал такой широкий набор синтаксических конструкций и встроенных функций, что, вероятно, не существует ни одного компилятора, поддерживающего все возможности этого языка. Простое перечисление всех вариантов вызова компилятора занимало две страницы руководства для пользователей. В результате неопытный пользователь долго и мучительно пытался сообразить, как же откомпилировать его маленькую простейшую учебную программу. Вообще говоря, обилие дополнительных возможностей неблагоприятно сказывается на работе пользователя, подталкивая его к выбору по принципу «скорее всего, так» и приводя к последствиям неправильного выбора. Разработчик должен тщательно рассмотреть каждую предоставляемую возможность, сопоставляя ее полезность и степень усложнения ПО. Когда имеются сомнения, безопаснее отказаться от рассматриваемого варианта. Множество доступных мелких возможностей не повысит конкурентоспособности продукта, а скорее всего, негативно по-

195

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

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

Подготовка внешних спецификаций

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

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

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

основные компоненты, затем просто компоненты и, наконец, функ-

196

ции. Допустим, одна из основных компонент – управляющий библиотекой. В рамках этой основной компоненты примером компоненты может быть администратор секретности. В рамках этой компоненты примером функции будет запрос СООБЩИТЬ О НАРУШЕНИЯХ СЕКРЕТНОСТИ.

Детальный внешний проект каждой функции пользователя должен освещать следующие вопросы:

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

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

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

4.Характеристики надежности. Описание воздействия всех возможных отказов функций на саму систему, файлы и пользователя.

197

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

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

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

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

Проверка правильности внешних спецификаций

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

На этом этапе ошибки следует обязательно исправлять. Цель всякого процесса проверки правильности (или тестирования) – найти

198

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

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

ирекомендуется применять их все.

1.Контроль по правилу «n плюс-минус один».

2.Контроль со стороны пользователя.

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

4.Ручная имитация. Эффективный прием проверки – подготовить тесты и затем воспользоваться детальными внешними спецификациями для имитации поведения системы.

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

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

3.2.5. Проектирование архитектуры программы

Следующий этап проектирования программного обеспечения – проектирование архитектуры программы [4]. Он включает определение всех модулей программы, их иерархии и сопряжений между ни-

199

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

Традиционный метод борьбы со сложностью – принцип «разделяй и властвуй», часто называемый «модуляризацией». На практике, однако, этот подход часто не приводит к ожидаемому уменьшению сложности. В [2] указано три причины подобной неудачи:

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

2.При проектировании остались невыявленными общие функции, вследствие чего они рассредоточены (и по-разному реализованы) в разных модулях.

3.Модули взаимодействуют посредством совместно используемых или общих данных самым неожиданным образом.

Методология проектирования, называемая композиционным проектированием [2], – это принцип проектирования, рассматриваемый здесь на примере проектирования структуры программы. Композиционное проектирование состоит, по существу, из двух компонент: системы явных проектных оценок, позволяющих решить все три перечисленные выше проблемы и еще целый ряд дополнительных проблем, и ряда мыслительных процессов, обеспечивающих разбиение программы на множество модулей, их сопряжений и отношений. В результате композиционного проектирования достигается минимальная сложность структуры программы. Такую программу легче понимать, сопровождать и адаптировать.

Независимость модулей

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

200