Методология проектирования для надежных программных систем: резюме научной статьи

metodologiya proektirovaniya dlya nadezhnyh programmnyh sistem rezyume nauchnoj stati

Давайте углубимся в «Методологию проектирования надежных программных систем», опубликованную Барбарой Лесковой в 1972 году.

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

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

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

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

Несомненно, нет никакой гарантии, что это скрыто в отладке: как сказал Дейкстра, «тестирование программы можно использовать, чтобы показать наличие ошибок, но никогда не показать их отсутствие».

Чтобы быть уверенными, что наша система работает правильно, нам нужно тестирование, которое отвечает следующим условиям:

  1. Мы можем создать минимальный набор соответствующих тестов.
  2. Все тестовые случаи могут быть сгенерированы в наборе.

Решения этих проблем не лежат в сфере отладки, не имеющей контроля над источниками проблем.

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

Далее, в документе утверждается, что надежность является основной проблемой сложных систем. Далее дается следующее определение сложных систем:

  1. Система имеет много состояний и трудно организовать программную логику для правильной обработки.
  2. Это требует слаженного сотрудничества нескольких человек.

Критерии хорошего дизайна:

Чтобы обуздать дизайн сложной системы, нам нужно использовать модульность.

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

Связи определены Парнасом следующим образом:

Связи между модулями – это предположения, какие модули делают друг о друге.

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

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

Некоторые распространенные проблемы:

  1. Модуль делает слишком многое.
  2. Общая функция распределена между многими разными модулями.
  3. Модуль обращается неожиданно с обычными данными.

Возникает следующий вопрос: что такое хорошая модульность?

Для ответа на это мы используем две методики: уровни абстракции для решения внутренней сложности системы и структурированное программирование для представления дизайна в программном обеспечении.

Уровни абстракции:

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

Группа связанных функций составляет уровень абстракции. Каждый уровень может иметь следующие два типа функций:

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

Уровни абстракции регулируются следующими двумя правилами:

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

Структурированное программирование:

Структурированная программа определяет способ прохождения управления между разными разделами в системе.

Он определяется следующими правилами:

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

Вернемся к вопросу, который был задан ранее: как мы определяем хорошую модульность?

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

  1. Они должны соблюдать правила, налагаемые уровнями абстракции и структурированного программирования.
  2. Передача данных между разделами должна производиться с использованием явных аргументов. Аргументы передаются внешним функциям другого раздела.
  3. Разделы должны быть логически независимы. Функции в разделе должны поддерживать собственную абстракцию только

Следующий вопрос, возникающий после того, как мы выяснили, как определить хорошую модульность, это — как мы достигаем этого в нашем дизайне?

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

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

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

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

Далее в статье представлены некоторые указания по определению различных типов абстракций при проектировании системы:

  1. Абстракция ресурсов: для каждого аппаратного ресурса в системе. Мы можем сравнить характеристики абстрактного ресурса с основным ресурсом.
  2. Абстрактные характеристики данных: как они хранятся.
  3. Упрощение путем ограничения информации, которую раздел должен знать или иметь к ней доступ.
  4. Упрощение через обобщение путем идентификации функций, выполняющих общую задачу. Такие функции можно сгруппировать в одном разделе. «Существование такой группы упрощает другие разделы, которым нужно только обращаться к функциям низшего раздела, а не выполнять сами задачи».
  5. Обслуживание и модификация системы: функции, выполняющие задачи, определение которых может быть изменено в будущем, должны быть частью независимых разделов. Например, функции, которые имеют дело с подключением к определенному типу серверной части хранилища, поэтому если в будущем будет использоваться другая часть сервера, это повлияет только на функции этого раздела.

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

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

Вторая фаза происходит одновременно с первой; когда предлагаются абстракции, их полезность и практичность немедленно исследуются.

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

Следующий вопрос, который можно задать: как определить, когда дизайн окончен?

  1. Все главные абстракции были идентифицированы и соединены с разделом. Системные ресурсы были распределены между разными разделами и определены их позиции в иерархии
  2. Интерфейсы и поток управления между разделами четко определены. Были определены тестовые примеры для каждого раздела
  3. Можно написать основное руководство пользователя для системы

Добавить комментарий

Ваш адрес email не будет опубликован.