PrIS
.pdf
441
Рис. 20.12. Різні варіанти переходів у (із) складений стан.
Іноді бажано реалізувати ситуацію, коли вихід з окремого вкладеного стану відповідав би виходу і зі складеного стану теж. У цьому випадку зображають перехід, який безпосередньо виходить із вкладеного підстану за межу суперстану (перехід с на рис. 20.12). Аналогічно, допускається зображення переходів, що входять ззовні складеного стану в окремий вкладений стан (перехід а на рис. 20.12).
20.6.3. Синхронізаційні стани
Як уже зазначалося, поведінка паралельних підавтоматів незалежна одна від одної, що дозволяє реалізувати багатозадачність в програмних системах. Проте в окремих випадках може виникнути необхідність врахувати в моделі синхронізацію настання окремих подій. Для цієї мети в мові UML є спеціальний псевдостан, який називається синхронізаційним станом.
Синхронізаційний стан (synch state) позначається невеликим колом, усередині якого вміщений символ зірочки "*". Він використовується спільно з переходом-з'єднанням або переходом-розгалуженням для того, щоб явно вказати події в інших підавтоматах, роблять безпосередньо впливають на поведінку такого підавтомата.
Для ілюстрації використання синхронізаційних станів розглянемо спрощену ситуацію з моделюванням процесу спорудження будинку. Припустимо, що процес спорудження будинку передбачає будівельні роботи (зведення фундаменту і стін, зведення даху і внутрішні роботи), роботи з електрифікації будинку (підведення електричної лінії, прокладка прихованої електромережі і встановлення освітлювальних ламп). Очевидно, два цих комплекси робіт можуть виконуватися паралельно, проте між ними є деякий взаємозв'язок.
Зокрема, прокладання прихованої електромережі може початися лише після того, як буде завершено зведення фундаменту і стін. А внутрішні роботи треба почати лише після того, як буде закінчене прокладання прихованої електромережі. Інакше внутрішні роботи доведеться виконувати повторно. Розглянуті особливості синхронізації
442
цих паралельних процесів враховані на відповідній діаграмі станів за допомогою двох синхронізаційнчих станів (рис. 20.13).
Рис. 20.13. Діаграма станів для прикладу з будівництвом будинку.
На завершення цього розділу розглянемо діаграму станів, яка є прикладом моделювання поведінки конкретного об'єкту, – процесу функціонування телефонного апарату (рис. 20.14). Цей приклад ілюструє всі основні особливості графічної нотації, що використовується під час побудови діаграми станів.
Коротко прокоментуємо основні особливості цього прикладу. Ця діаграма станів відображає єдиний автомат з одним складеним станом. Поза цим складеним станом є тільки один стан "очікування", який характеризує справний і підключений до телефонної мережі телефонний апарат. Перехід у наступний стан відбувається при піднятті телефонної трубки. Перехід з атомарною дією "подати тоновий сигнал" переводить апарат у складений стан, а точніше – у початковий його підстан.
443
Рис. 20.14. Діаграма станів процесу функціонування телефонного апарату.
Далі телефонний апарат перебуватиме у стані "тоновий сиґнал". При цьому безперервно видаватиме цей сиґнал доти, поки не відбудеться подія-триґер "набір цифри (n)", або не закінчиться 15 секунд з моменту підняття трубки. У першому випадку апарат перейде у стан "набір номера", а в другому – у стан "закінчення часу очікування". Остання ситуація може бути результатом сумнівів з приводу "дзвонити – не дзвонити?", наслідком чого можуть стати гудки у трубці. При цьому нам нічого не залишається робити, як опустити її на важіль.
Під час набору номера виконується подія-триґер "набір цифри (n)” зі сторожовою умовою "номер неповний". Це означає, що якщо набраний телефонний номер не містить необхідної кількості цифр, то нам треба продовжувати набір чергової цифри, залишаючись у стані "набір номера".
Якщо ж набраний номер повний, то можна перейти у стан "невірний номер" або "з'єднання". У разі невірного номера (сторожова умова "невірний" істинна) нічого не залишається, як покинути складений стан, опустивши трубку на важіль. Якщо ж номер вірний, то відбувається з'єднання з цим номером.
Проте в результаті з'єднання може трапитися, що апарат абонента зайнятий (перехід у стан "зайнято") або вільний (перехід у стан "дзвінок у абонента"). У першому випадку можна повторити телефонування, заздалегідь опустивши трубку на важіль (вихід зі складеного стану). У другому випадку відбувається перевірка сторожової умови "розмова доступна". Якщо вона істинна, що відповідає зняттю трубки абонентом,
444
починається телефонна розмова. Інакше (ця умова не виконується, тобто вона помилкова) телефон абонента продовжуватиме дзвонити, сповіщаючи нас про відсутність останнього або про неможливість з якоїнебудь причини вести розмову по телефону. При цьому нам нічого не залишається, як опустити трубку на важіль.
Якщо ж розмова відбулася, то, після слів прощання і виконання сторожової умови "підтвердження" на закінчення розмови, ми знову опускаємо трубку. При цьому телефонний апарат переходить у стан "очікування", в якому може перебувати невизначено довго.
Примітка
Строго кажучи, розглянутий приклад відображає не всі аспекти поведінки навіть такого нескладного на перший погляд пристрою, яким є звичайний телефонний апарат. Зокрема, така діаграма станів може бути доповнена переходом і з стану "очікування" за подією-триґером "телефонний дзвінок", який може відразу перевести нас у внутрішній підстан "розмова", якщо ми вирішили зняти телефонну трубку (перехід типу а на рис. 20.12).
Інша модифікація може бути пов'язана з бажанням повторно використовувати набраний номер у разі коротких гудків "зайнято" у абонента. Рішення цієї задачі може бути реалізоване на основі використання історичного стану замість початкового підстану, який запам'ятовуватиме в пам'яті апарату одного разу набраний номер. Читачеві пропонується самостійно доповнити діаграму станів як вправу.
20.7. Рекомендації з побудови діаграм станів
Основні особливості побудови діаграм станів були розглянуті при описі відповідних модельних елементів, що входять в пакет Автомати. Проте деякі моменти не знайшли віддзеркалення, про що необхідно сказати на закінчення цього розділу.
За своїм призначенням діаграма станів не є обов'язковим поданням моделі і наче "приєднується" до того елементу, який, за задумом розробників, має нетривіальну поведінку протягом свого життєвого циклу. Наявність у системи декількох станів, що відрізняються від простої дихотомії "справний, – несправний", "активний – неактивний", "очікування – реакція на зовнішні дії", вже служить ознакою необхідності побудови діаграми станів. Як початковий варіант діаграми станів, якщо немає очевидних міркувань з приводу станів об'єкту, можна скористатися цими суперстанами, розглядаючи їх як складені й уточнюючи їх (деталізуючи їх внутрішню структуру) в міру розгляду логіки поведінки об'єкту.
445
Під час виділення станів і переходів треба пам'ятати, що тривалість спрацьовування окремих переходів має бути істотно меншою, ніж перебування модельованого об'єкту у відповідних станах. Кожний зі станів повинен характеризуватися певною стійкістю в часі. Всі переходи мають бути явно специфіковані, інакше побудована діаграма станів є або неповною, або помилковою.
Під час розроблення діаграми станів треба постійно стежити, щоб об'єкт у кожний момент міг перебувати лише в одному стані. Якщо це не так, то така обставина може бути як наслідком помилки, так і неявною ознакою наявності паралельності поведінки модельованого об'єкту. В останньому випадку треба явно специфікувати необхідну кількість підавтоматів, вклавши їх у той складений стан, який характеризується порушенням умови одночасності.
Треба обов'язково перевіряти, що ніякі два переходи з одного стану не можуть спрацювати одночасно (вимога відсутності конфліктів у переходів). Наявність такого конфлікту може служити ознакою помилки або неявної паралельності типу розгалуження певного процесу на два і більше. Якщо паралельність за задумом розробника відсутня, то необхідно ввести додаткові сторожові умови або змінити ті, що існують, щоб виключити конфлікт переходів. За наявності паралельності треба замінити переходи, які конфліктують, одним паралельним переходом типу розгалуження.
Використання історичних станів виправдане у тому випадку, коли необхідно організувати опрацювання виняткових ситуацій (переривань) без втрати даних або виконаної роботи. При цьому застосовувати історичні стани, особливо глибокі, треба з відомою часткою обережності. Треба пам'ятати, що кожний з підавтоматів може мати тільки один історичний стан. Інакше можливі помилки, особливо, коли підавтомати зображаються на окремих діаграмах станів.
І, нарешті, зазначимо, що деякі додаткові конструкції автоматів, такі як точки динамічного вибору (dynamic choice points) або точки з'єднання (junction points), у навчальному посібнику не знайшли віддзеркалення. Це зроблено з тієї причини, що такі модельні елементи хоча й дозволяють моделювати складніші аспекти динамічного керування поведінкою об'єкту, не є базовими. Відповідна інформація міститься в ориґінальній документації з мови UML.
Контрольні запитання
1.Призначення діаграми станів.
2.Автомати.
446
3.Позначення стану.
4.Ім'я стану.
5.Список внутрішніх дій.
6.Початковий стан.
7.Кінцевий стан.
8.Переходи між станами.
9.Сторожова умова.
10.Складений стан і підстан.
11.Паралельні підстани.
12.Історичний стан.
13.Складні переходи.
14.Переходи між паралельними станами.
15.Переходи між складеними станами.
16.Синхронізаційні стани.
447
РОЗДІЛ 21. Діаграма діяльності (activity diagram)
Стан дії
Переходи
Доріжки
Об'єкти
Рекомендації з побудови діаграм діяльності
Під час моделювання поведінки проектованої або аналізованої системи виникає необхідність не тільки подати процес зміни її станів, але й деталізувати особливості алгоритмічної і логічної реалізації виконуваних системою операцій. Традиційно з цією метою використовувалися блок-схеми або структурні схеми алгоритмів (такі як, наприклад, на рис. 3.1). Кожна така схема акцентує увагу на послідовності виконання певних дій або елементарних операцій, які за сукупністю приводять до отримання бажаного результату.
Алгоритмічні і логічні операції, що мають виконуватись в певній послідовності, оточують нас постійно. Звичайно, ми не завжди замислюємося над тим, що подібні операції відносяться до наукових категорій. Наприклад, щоб зателефонувати, нам заздалегідь треба зняти трубку або увімкнути телефон. Для запарювання кави або чаю необхідно спочатку закип'ятити воду. Щоб відремонтувати двигун автомобіля, треба здійснити цілий ряд нетривіальних операцій, таких як розбирання силового аґреґата, зняття ґенератора і деякі інші.
Важливо підкреслити ту обставину, що зі збільшенням складності системи строге дотримання послідовності виконуваних операцій набуває все важливішого значення. Порушення послідовності операцій під час ремонту двигуна може привести до його поламки або виходу з ладу. Ще катастрофічніші події можуть відбутися у разі відхилення від встановленої послідовності дій при зльоті або посадці авіалайнера, запуску ракети, реґламентних робіт на АЕС.
Для моделювання процесу виконання операцій в мові UML використовуються так звані діаграми діяльності. Вживана в них графічна нотація багато в чому схожа на нотацію діаграми станів, оскільки на діаграмах діяльності також присутні позначення станів і переходів. Відмінність полягає в семантиці станів, які використовуються для подання не діяльностей, а дій, і у відсутності на переходах сигнатури подій. Кожне перебування на діаграмі діяльності відповідає виконанню деякої елементарної операції, а перехід в наступний стан спрацьовує
448
тільки після завершення операції в попередньому стані. Діаграма діяльності подається у формі графа діяльності, вершинами якого є стани дій, а дугами – переходи від одного стану дії до іншого.
Отже, діаграми діяльності можна вважати окремим випадком діаграм станів. Саме вони дозволяють реалізувати в мові UML особливості процедурного і синхронного керування, обумовленого завершенням внутрішніх діяльностей і дій. Метамодель UML надає для цього необхідні терміни і семантику. Основним напрямом використання діаграм діяльності є візуалізація особливостей реалізації операцій класів, коли необхідно зобразити алгоритми їх виконання. При цьому кожний стан може бути виконанням операції деякого класу або її частини, дозволяючи використовувати діаграми діяльності для опису реакцій на внутрішні події системи.
У контексті мови UML діяльність (activity) є деякою сукупністю окремих обчислень, що виконуються автоматом. При цьому окремі елементарні обчислення можуть приводити до деякого результату або дії (action). На діаграмі діяльності відображається логіка або послідовність переходу від однієї діяльності до іншої, при цьому увага фіксується на результаті діяльності. Сам же результат може привести до зміни стану системи або повернення деякого значення.
Примітка
Хоча діаграма діяльності призначена для моделювання поведінки систем, час на цій діаграмі в явному вигляді відсутній. Ситуація тут багато в чому аналогічна до діаграми станів.
21.1. Стан дії
Стан дії (action state) є спеціальним випадком стану з деякою вхідною дією і принаймні одним переходом, що виходить зі стану. Цей перехід неявно припускає, що вхідна дія вже завершилася. Стан дії не може мати внутрішніх переходів, оскільки він є елементарним. Звичайне використання стану дії полягає в моделюванні одного кроку виконання алгоритму (процедури) або потоку керування.
Графічно стан дії зображається фіґурою, що нагадує прямокутник, бічні сторони якого замінені опуклими дугами (рис. 21.1). Всередині цієї фіґури записується вираз дії (action-expression), яка має бути унікальною в межах однієї діаграми діяльності.
а) Звичайна дія б) Вираз Рис. 21.1. Графічне зображення стану дії.
449
Дія може бути записана природною мовою, у деякому псевдокоді або мові програмування. Жодних додаткових або неявних обмежень при записі дій не накладається. Рекомендується як ім'я простої дії використовувати дієслово зі словами пояснень (рис. 21.1, а). Якщо ж дія може подаватися в деякому формальному вигляді, то доцільно записати його на тій мові програмування, на якій передбачається реалізовувати конкретний проект (рис. 21.1, б).
Іноді виникає необхідність подати на діаграмі діяльності деяку складну дію, яка, своєю чергою, складається з декількох простіших дій. У цьому випадку можна використовувати спеціальне позначення так званого стану піддіяльності (subactivity state). Такий стан є графом діяльності і позначається спеціальною піктограмою у правому нижньому кутку символа стану дії (рис. 21.2). Ця конструкція може застосовуватися до будь-якого елемента мови UML, яка підтримує "вкладеність" своєї структури. При цьому піктограма може бути додатково позначена типом вкладеної структури.
Рис. 21.2. Графічне зображення стану піддіяльності.
Кожна діаграма діяльності повинна мати єдиний початковий і єдиний кінцевий стани. Вони мають такі самі позначення, як і на діаграмі станів (див. рис. 25.4). При цьому кожна діяльність починається в початковому стані і закінчується в кінцевому стані. Саму діаграму діяльності прийнято розташовувати так, щоб дії слідували зверху вниз. У цьому випадку початковий стан зображається у верхній частині діаграми, а кінцевий – в її нижній частині.
21.2. Переходи
Перехід як елемент мови UML розглядався в розділі 20. Під час побудови діаграми діяльності використовуються тільки нетриґерні переходи, тобто такі, які спрацьовують відразу після завершення діяльності або після виконання відповідної дії. Цей перехід переводить діяльність в подальший стан відразу, як тільки закінчиться дія у
450
попередньому стані. На діаграмі такий перехід зображається суцільною лінією зі стрілкою.
Якщо зі стану дії виходить єдиний перехід, то він може бути без мітки. Якщо ж таких переходів декілька, то спрацювати може тільки один з них. Саме у цьому випадку для кожного з таких переходів має бути явно записана сторожова умова у прямокутних дужках (див. розділ 20). При цьому для всіх переходів, що виходять з деякого стану, повинна виконуватися вимога істинності тільки одного з них. Подібний випадок зустрічається тоді, коли послідовно виконувана діяльність повинна розділитися на альтернативні гілки залежно від значення деякого проміжного результату. Така ситуація отримала назву розгалуження, а для її позначення застосовується спеціальний символ.
Графічно розгалуження на діаграмі діяльності позначається невеликим ромбом, усередині якого немає жодного тексту (рис. 21.3). У цей ромб може входити тільки одна стрілка від того стану дії, після виконання якого потік керування має продовжитися однією з гілок, що взаємно виключають одна одну. Прийнято вхідну стрілку приєднувати до верхньої або лівої вершини символа розгалуження. Стрілок, що виходять, може бути дві або більше, але для кожної з них явно вказується відповідна сторожова умова у формі булевого виразу.
Як приклад розглянемо фраґмент відомого алгоритму знаходження кореня квадратного рівняння. У загальному випадку після зведення рівняння другого степеня до канонічного вигляду: а*х*х + b*х + c = 0 необхідно обчислити його дискримінант. Причому, у разі від’ємного дискримінанта рівняння не має розв’язків на множині дійсних чисел, і подальші обчислення мають припинятися. При невід’ємному дискримінанті рівняння має розв’язки, корені якого можуть бути отримані на основі конкретної формули.
Графічно фраґмент процедури обчислення кореня квадратного рівняння може бути зображений у вигляді діаграми діяльності з трьома станами дії і розгалуженням (рис. 21.3). Кожний з переходів, що виходять зі стану "Обчислити дискримінант", має сторожову умову, що визначає єдину гілку, якою може продовжуватися процес обчислення кореня залежно від знаку дискримінанта. Очевидно, що у разі його від’ємності, ми відразу потрапляємо в кінцевий стан, тим самим завершуючи виконання алгоритму загалом.
Примітка
Строго кажучи, перший зі станів цього алгоритму треба вважати станом піддіяльності, оскільки зведення квадратного рівняння до канонічного вигляду може вимагати декількох елементарних дій (зведення подібних і перенесення окремих членів рівняння з правої його
