Skip to content

ООП Лекция 17. MBO и Каналы управления. ДПДД

Vladislav Mansurov edited this page Jun 13, 2022 · 3 revisions

ДПС и ТПС, Супер-классы.

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

  • Cостояний, который может принимать объект;
  • Событий, которые переводит объект из одного состояние в другое;
  • Правил перехода;
  • Действий состояний, которые выполняются при перехода объекта состояний. Каждому состоянию, ставит соответствующее действие.

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

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

Пусть у нас есть какие-то состояния и могут быть они отличаться.

image

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

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

Метка Название Данные Источник Приемник
... ... ... ... ...

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

  • Задача/Запрос;
  • Появления/Уничтожение объекта во время выполнения;
  • Ассоциативный объект, отвечающий за связь других объектов(динамическое поведение связи);
  • Пассивный объект, чтобы включить их в общую схему событийного взаимодействия;
  • Объекты, выполняющие некоторые алгоритмы тяжело и долго, включить их в асинхронное взаимодействие.

Диаграмма потоков данных действий (ДПДД).

Пусть у нас есть примерная такая блок-схема для нахождения длины вектора:

image

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

  • Нет зависимость по дынным;
  • Неизвестно откуда брать данные.

В 70-ые годы было предложено другое представление алгоритма. Требовалась оценка возможности распараллеливания вычислений. Когда мы говорим о распараллеливании вычислений возникает проблема с доступностью данных. Де-Марко предложил диаграмму, которая позволяет оценить не только алгоритмический порядок действий, но и доступность данных для выполнения того или иного действия. И тогда была предложена ДПДД.

Мы разбиваем наш алгоритм на процессы, которые происходят для выполнения обработчика состояний. Диаграмма строится для каждого состояния, каждой модели состояний. И каждый из них отвечает на вопрос, что он делает. Каждое действие можно выделить как процесс, который происходит.

image

Каждое действие мы можем выделить как процесс, который происходит. Каждый процесс отвечает на вопрос: "Что он делает"? Вычисляет, проверяет и так далее. Пишем ключевой литерал - A, номер процесса - 1, определяем, что он делает - Вычислить sum := 0. Таким образом, мы выделили процесс, который вычисляет sum.

Далее, у нас идет цикл. И i равно нулю, для этого выделяем процессA2, Вычислить i := 0. Затем идет условие и здесь новые процесс A3 - Проверить i, но нам надо откуда-то получить данные i, то есть процесс А3 должен выполняться после А2 и указываем поток данных, простой стрелкой, с пометкой (i), а () обозначает, что данные неустойчивые, то есть оно используется только во время выполнения нашего действия.

В зависимости от проверки A3 возможно 2 варианта:

  1. A4 - Вычислить sum := sum + arr[i]^2. Этот процесс использует условие A3. У нас идет условное управление, поэтому перечеркиваем линию и пишем условие i < count. Откуда нам взять count? Данные самого объекта рассматриваются, как архив данных. Доступ должен происходить к данным через процесс, поэтому заведем A5 - Считать count. Так же нам еще нужна сумма, берем её из A1.
  2. После того, как вычислили сумму, увеличиваем инкремент- A6. Пунктирная стрелка говорит о том, что процесс A6 может выполниться только тогда, когда выполнен этот процесс A4.

На выходе получаем результат и отправляем его в терминатор.

Виды поток данных ДПДД:

  1. Условные (штрих-пунктирная с обозначением условия перехода);

    image

  2. C передачей данных;

    image

  3. Безусловные (штрих-пунктирная без обозначения условия);

    image

Важные моменты

  • Стрелками мы показываем потоки данных, если направлены к процессу – то входные данные, если от – то выходные. Мы всегда помечаем стрелочку теми данными, которые передаются. Каждая стрелочка - это одно данное

  • Если мы читаем атрибуты самого объекта, то мы просто записываем имя атрибута. Если это объект того же класса, но это другой объект, ИЛИ это объект другого класса, то имя надо аннотировать впереди идентификатора, например, array.count - это будет говорить о том, что это другой объект, а не тот же самый.

  • Считывание данных атрибута самого объекта, другого объекта того же класса или других классов мы рассматриваем как архив данных.

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

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

  • Устойчивые и неустойчивые данные. Если данное порождается во время выполнения действия, его отмечают как неустойчивое. Данные из архива устойчивы, все другие – неустойчивые(их мы берем в круглые скобки).

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

Выделяют 4 типа процессов

  • Аксессоры – единственная цель – получить доступ к архиву данных 4 вида:
    • Создания/Уничтожения
    • Чтения/Записи
  • Генераторы событий – процесс, который создает на выходе событие:
    • Принять событие

      image

    • Породить событие

  • Преобразования/Вычисления – процесс, который выполняет какие-либо преобразования данных
  • Проверки – результат – условный переход

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

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

  • Когда мы выделяем общие процессы, то мы решаем задачу дублирования кода.
  • Процессы выполняют одни и те же вычисления
  • Процессы, которые читают или записывают одни и те же атрибуты
  • Создают или уничтожают одни и те же объекты
  • Процессы, которые принимают одни и те же атрибуты от терминаторов
  • Процессы, которые порождают одни и те же события
  • Процессы, которые создают на выходе одни и те же данные
  • Процессы, которые порождают одни и те же выходы условного управления

Чтобы решить эту задачу, все процессы мы объединяем в таблицу процессов состояний (выделяем действия и выносим их для общего использования). Возможно несколько представлений этой таблицы. Сначала мы разбиваем эту таблицу по дпдд: “на данном дпдд происходят такие процессы, другая дпдд - другие процессы и тд.”. Потом пытаемся проанализировать и объединить все те процессы, которые проходят в одной модели состояния. Чтобы было удобнее, можно преобразовать это по типу действия, которое происходит. То есть можно сгруппировать аксессоры, преобразователи и тд. и посмотреть есть ли что-то общее. Обработав так процессы для каждой модели состояния, мы можем объединить это в одно целое. Так мы четко выделяем общие процессы.

Аксессоры определяются для того объекта, к архиву данных которого происходит доступ. Аксессор создания - это конструктор самого объекта. Аксессор уничтожения - деструктор самого объекта. Аксессоры чтения/записи - методы объекта.

Правила выполнения процессов:

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

Модель взаимодействие объектов (МВО).

На основе выделенных аксессоров строится МВО.

Есть объект A, объект B, рисуем стрелку A -> B, что говорит о том, что A использует аксессор объекта B, на стрелке помечаем идентификатор процесса, где взаимодействие синхронное (Модель доступа)

image

МВО - модель взаимодействия объектов. Мы рассматриваем только нашу подсистему или домен. Что ВОВНЕ нас не интересует, но ИЗВНЕ могут приходить события.

МВО строится таким образом, что вверху располагаются модели состояний объектов, которые боле осведомлены о нашей подсистеме. Идея - свести так, чтобы главный был один.

Все события разделяем на две группы:

  • Внешние события, которые приходят извне.
  • Внутренние события, которые происходят внутри нашей подсистемы.

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

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

image

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

Внешние события разделяем на две группы:

  • Незапрашиваемые - не являются следствием предыдущего действия нашей подсистемы.
  • Запрашиваемые - являются результатом действия нашей подсистемы.

В зависимости от того, откуда пришло не запрашиваемое событие, рассматриваем схемы:

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

Мы нарисовали модель взаимодействия объектов в нашей подсистеме, но хотелось бы проследить, как изменяются состояния объектов нашей подсистемы с приходом какого-либо не запрашиваемого события извне. Это важный момент! Для того чтобы проверить корректность нашей модели, мы должны перебрать все возможные варианты. Здесь необходимо так называемое моделирование: мы генерим всевозможные начальные состояния объектов нашей подсистемы, и для каждого набора начальных состояний анализируем, как в этом начальном состоянии система реагирует на все не запрашиваемые события. И так для каждой генерации.

Каналы Управления (КУ)

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

При этом здорово отметить, что МДО - взаимодействие синхронное, а в МВО - асинхронное. Но здесь не все так просто, выделили модели состояний, модель взаимодействия, но нам надо проверить все же нормально, для этого проводится процесс проектирования результатов, строятся КУ, как у нас происходит процесс при незапрашиваемое событие, причем для каждого событие строится свои каналы управления. Дело в том что у нас может быть несколько начальных состояний нашей подсистемы. Первым делом, что мы должны сделать - выделить в каких начальных состояний могут находится наши подсистемы, далее смотрим какие незапрашиваемые событие могут приходить, неважно от каких терминаторов и смотрим как система реагирует на эти событие.

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

image

Правила построения КУ:

  • КУ должны иметь конец.
  • Как правило при построении выделяют сначала главную модель состояний, и затем уже остальные. Тут также неважно будут реагировать или изменять модель состояний, которые мы просматриваем на данном этапе, все равно выделяем все состояния нашей подсистемы.
  • Название состояний, берется с ДПС.
  • Всегда помечаем, какое незапрашиваемое событие пришло, в результате которого модель состояния может перейти в другое
  • При моделировании, тут будет важно время, временная школа сверху вниз
  • Для каждого состояния выделяются два времени (не указываем, если несущественное):
    • Время выполнения действия - время, которое переводит объект в это состояние. Это время записывается внутри прямоугольника.
    • Время задержки - это то время, которое объект должен находиться в этом состоянии. Например, для дверей есть состояние "двери закрываются". Закрытие дверей не происходит мгновенно, это происходит за какое то время. Это время записывается вне прямоугольника.

Процесс имитирования каналов управления:

  • Сгенерировать все начальные состояния.
  • Для каждой генерации принять все незапрашиваемые события.
  • Мы должны прийти в какие то окончательные состояния.
Clone this wiki locally