Опубликован: 23.10.2005 | Уровень: специалист | Доступ: платный
Лекция 2:

Образец проектирования: многопанельные интерактивные системы

< Лекция 1 || Лекция 2: 123456 || Лекция 3 >
Аннотация: Создадим образец проектирования, иллюстрирующий ОО-метод. Он будет сравниваться с другими подходами, в частности с функциональной декомпозицией сверху вниз, что позволит продемонстрировать выдающиеся возможности Метода.

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

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

Многопанельные системы

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

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

Примером может служить система резервирования авиабилетов, где состояния представляют такие шаги обработки, как User Identification (Идентификация Пользователя), Enquiry on Flights (Запрос Рейса в нужное место и требуемую дату), Enquiry on Seats (Запрос Места на выбранный рейс), Reservation (Резервирование).

Типичная панель для состояния Enquiry on Flights (Запрос Рейса) может выглядеть как на рис. 2.1 (рисунок иллюстрирует только идею и не претендует на реализм или хороший эргономичный дизайн). Экран показан на шаге, завершающем состояние, ответы пользователя в соответствующих окнах показаны курсивом, реакция системы на эти ответы (показ доступных рейсов) дана жирным шрифтом.

Панель "Запрос Рейса"

Рис. 2.1. Панель "Запрос Рейса"

Сессия начинается в начальном состоянии Initial и заканчивается в заключительном состоянии Final. Мы можем представить всю структуру графом переходов, показывающим возможные состояния и переходы между ними. Ребра графа помечены целыми, соответствующими возможному выбору пользователя следующего шага при завершении состояния. На рис. 2.2 показан граф переходов системы резервирования авиабилетов.

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

  • G1 Граф может быть большим. Довольно часто можно видеть приложения, включающие сотни состояний с большим числом переходов.
  • G2 Структура системы, как правило, изменяется. Проектировщики не могут предвидеть все возможные состояния и переходы. Когда пользователи начинают работать с системой, они приходят с запросами на изменение системы и расширение ее возможностей.
  • G3 В данной схеме нет ничего специфического для конкретного приложения. Система резервирования авиабилетов является лишь примером. Если вашей компании необходимо несколько таких систем для собственных целей или в интересах различных клиентов, то большим преимуществом было бы определить общий проект или, еще лучше, множество модулей, допускающих повторное использование в разных приложениях.
Граф переходов в системе резервирования авиабилетов

Рис. 2.2. Граф переходов в системе резервирования авиабилетов

Первая напрашивающаяся попытка

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

BEnquiry:
    "Отобразить панель Enquiry on flights"
    repeat
        "Чтение ответов пользователя и выбор C следующего шага"
        if "Ошибка в ответе" then
            "Вывести соответствующее сообщение" end
    until not "ошибки в ответе" end
    "Обработка ответа"
    case C in
        C0: goto Exit,
        C1: goto BHelp,
        C2: goto BReservation,
        ...
    end

Аналогичный вид имеют блоки для каждого состояния.

Что можно сказать об этой структуре? Ее нетрудно спроектировать, и она делает свое дело. Но с позиций программной инженерии она оставляет желать много лучшего.

Наиболее очевидная критика связана с присутствием инструкций goto (реализующих условные переходы подобно переключателю switch языка C или "Вычисляемый Goto" Fortran), из-за чего управляющая структура выглядит подобно "блюду спагетти" и чревата ошибками.

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

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

Чтобы получить не просто систему, а хорошую систему, придется еще поработать.

< Лекция 1 || Лекция 2: 123456 || Лекция 3 >
Алексей Щербанов
Алексей Щербанов
Россия, г. Оренбург
Ксения Маковецкая
Ксения Маковецкая
Россия, Москва, МГЮА им. О.Е. Кутафина, 2014