PrIS
.pdf391
Варіанти використання класів відповідають операціям цього класу, оскільки сервіс класу є за суттю виконанням операцій певного класу. Деякі варіанти використання можуть відповідати застосуванню тільки однієї операції, тоді як інші – скінченної множини операцій, визначених у вигляді послідовності операцій. Одночасно одна операція може бути необхідна для виконання декількох сервісів класу і тому з'являтиметься в декількох варіантах використання цього класу.
Реалізація варіанту використання залежить від типу елементу моделі, в якому він визначений. Наприклад, оскільки варіанти використання класу визначаються за допомогою операцій цього класу, вони реалізуються відповідними методами. З іншого боку, варіанти використання підсистеми реалізуються елементами, з яких складається така підсистема. Оскільки підсистема не має своєї власної поведінки, всі пропоновані підсистемою сервіси мають бути композицією сервісів, пропонованих окремими елементами цієї підсистеми, тобто класами. Ці елементи можуть взаємодіяти один з одним для сумісного забезпечення необхідної поведінки окремого варіанту використання. Таке сумісне забезпечення необхідної поведінки описується спеціальним елементом мови UML – кооперацією або співпрацею, який буде розглянутий у розділі 23, присвяченому побудові діаграм кооперації. Тут лише відзначимо, що кооперації використовуються як для уточнення специфікацій у вигляді варіантів використання нижніх рівнів діаграми, так і для опису особливостей їх подальшої реалізації.
Якщо як модельована сутність виступає система або підсистема найвищого рівня, то окремі користувачі варіантів використання цієї системи моделюються акторами. Такі актори, будучи внутрішніми по відношенню до модельованих підсистем нижніх рівнів, часто в явному вигляді не вказуються, хоча й присутні неявно в моделі підсистеми. Замість цього варіанти використання безпосередньо звертаються до цих модельних елементів, які містять в собі подібні неявні актори, тобто екземпляри яких грають ролі таких акторів при взаємодії з варіантами використання. Ці модельні елементи можуть міститися в інших пакетах або підсистемах. В останньому випадку ролі визначаються в тому пакеті, до якого відноситься відповідна підсистема.
Із системно-аналітичного погляду побудова діаграми варіантів використання специфікує не тільки функціональні вимоги до проектованої системи, але й виконує початкову структуризацію предметної області. Останнє завдання поєднує в собі не тільки вимоги до технічних рекомендацій, але є в деякому роді мистецтвом, вмінням виділяти головне в моделі системи. Хоча раціональний уніфікований процес не виключає ітеративне повернення в подальшому до діаграми варіантів використання для її модифікації, не викликає сумнівів той факт,
392
що будь-яка подібна модифікація вимагатиме змін у всіх інших відображеннях системи. Тому завжди необхідно прагнути до можливо точнішого зображення моделі саме у формі діаграми варіантів використання.
Якщо ж варіанти використання застосовуються для специфікації частини системи, то вони будуть еквівалентні відповідним варіантам використання в моделі підсистеми для частини відповідного пакету. Важливо розуміти, що всі сервіси системи мають бути явно визначені на діаграмі варіантів використання, і ніяких інших сервісів, які відсутні на цій діаграмі, проектована система не може виконувати за визначенням. Понад це, якщо для моделювання реалізації системи використовуються відразу декілька моделей (наприклад, модель аналізу і модель проектування), то множина варіантів використання всіх пакетів системи має бути еквівалентна множині варіантів використання моделі загалом.
Контрольні запитання
1.Варіант використання.
2.Актори.
3.Інтерфейси.
4.Примітки в мові UML.
5.Відношення на діаграмі варіантів використання.
6.Відношення асоціації.
7.Відношення розширення.
8.Відношення узагальнення.
9.Відношення включення.
10.Навести приклад побудови діаграми варіантів використання.
РОЗДІЛ 19. Діаграма класів (class diagram)
Клас
Відношення між класами
Інтерфейси
Об'єкти
Шаблони або параметризовані класи
Рекомендації з побудови діаграм класів
393
Центральне місце в ООАП займає розроблення логічної моделі системи у вигляді діаграми класів. Нотація класів у мові UML проста й інтуїтивно зрозуміла всім, хто коли-небудь мав досвід роботи з CASEінструментами. Схожа нотація застосовується і для об'єктів – екземплярів класу — з тією відмінністю, що до імені класу додається ім'я об'єкту і весь напис підкреслюється.
Нотація UML надає широкі можливості для відображення додаткової інформації (абстрактні операції і класи, стереотипи, загальні і приватні методи, деталізовані інтерфейси, параметризовані класи). При цьому можливе використання графічних зображень для асоціацій і їх специфічних властивостей, таких як відношення аґреґації, коли складовими частинами класу можуть виступати інші класи.
Діаграма класів (class diagram) служить для подання статичної структури моделі системи в термінології класів об'єктно-орієнтованого програмування. Діаграма класів може відображати, зокрема, різні взаємозв'язки між окремими сутностями предметної області, такими як об'єкти і підсистеми, а також описує їх внутрішню структуру і типи відношень. На цій діаграмі не вказується інформація про тимчасові аспекти функціонування системи. Із цього погляду діаграма класів є подальшим розвитком концептуальної моделі проектованої системи.
Діаграмою класів є деякий граф, вершинами якого є елементи типу "класифікатор", які зв'язані різними типами структурних відношень. Зазаначимо, що діаграма класів може також містити інтерфейси, пакети, відношення і навіть окремі екземпляри, такі як об'єкти і зв'язки. Коли говорять про цю діаграму, мають на увазі статичну структурну модель проектованої системи. Тому діаграму класів прийнято вважати графічним поданням таких структурних взаємозв'язків логічної моделі системи, які не залежать або інваріантні в часі.
Діаграма класів складається з множини елементів, які в сукупності відображають декларативні знання про предметну область. Ці знання інтерпретуються в базових поняттях мови UML, таких як класи, інтерфейси і відношення між ними та їх складовими компонентами. При цьому окремі компоненти цієї діаграми можуть утворювати пакети для відображення загальнішої моделі системи. Якщо діаграма класів є частиною деякого пакету, то її компоненти мають відповідати елементам цього пакету, включаючи можливі посилання на елементи з інших пакетів.
У загальному випадку пакет статичної структурної моделі може зображатися у вигляді однієї або декількох діаграм класів. Декомпозиція деякого подання на окремі діаграми виконується з метою зручності і графічної візуалізації структурних взаємозв'язків предметної області. При цьому компоненти діаграми відповідають елементам статичної
394
семантичної моделі. Модель системи, своєю чергою, має бути узгоджена з внутрішньою структурою класів, яка описується на мові UML.
19.1. Клас
Клас (class) у мові UML служить для позначення множини об'єктів, які мають однакову структуру, поведінку і відношення з об'єктами інших класів. Графічно клас зображається у вигляді прямокутника, який додатково може бути розділений горизонтальними лініями на розділи або секції (рис. 19.1). У цих секціях можуть вказуватися ім'я класу, атрибути (змінні) і операції (методи).
Рис. 19.1. Графічне зображення класу на діаграмі класів.
Обов'язковим елементом позначення класу є його ім'я. На початкових етапах розроблення діаграми окремі класи можуть позначатися простим прямокутником із вказанням тільки імені відповідного класу (рис. 19.1, а). У міру опрацювання окремих компонентів, діаграми опису класів доповнюються атрибутами (рис. 19.1, б) і операціями (рис. 19.1, в).
Передбачається, що остаточний варіант діаграми містить якнайповніший опис класів, які складаються з трьох розділів або секцій. Іноді в позначеннях класів використовується додатковий четвертий розділ, в якому наводиться семантична інформація довідкового характеру або явно вказуються виняткові ситуації.
Навіть якщо секція атрибутів і операцій є порожньою, в позначенні класу вона виділяється горизонтальною лінією, щоб відразу відрізнити клас від інших елементів мови UML. Приклади графічного зображення класів на діаграмі класів наиведені на рис. 19.2. У першому випадку для класу "Прямокутник" (рис. 19.2, а) вказані тільки його атрибути – крапки на координатній площині, які визначають його розташування. Для класу "Вікно" (рис. 19.2, б) вказані тільки його операції, секція атрибутів залишена порожньою. Для класу "Рахунок" (рис. 19.2, в) додатково зображена четверта секція, в якій вказано виняток – відмову від опрацювання простроченої кредитної картки.
395
Рис.19.2. Приклади графічного зображення класів на діаграмі.
19.1.1. Ім'я класу
Ім'я класу має бути унікальним у межах пакету, який описується деякою сукупністю діаграм класів (можливо, однією діаграмою). Воно вказується в першій верхній секції прямокутника. На додаток до загального правила найменування елементів мови UML, ім'я класу записується по центру секції імені напівжирним шрифтом і має починатися з великої літери. Рекомендується як імена класів використовувати іменники, записані з практичних міркуваннях без пропусків. Необхідно пам'ятати, що саме імена класів утворюють словник предметної області під час ООАП.
У першій секції позначення класу можуть міститься посилання на стандартні шаблони або абстрактні класи, від яких утворений такий клас і, відповідно, від яких він успадковує властивості і методи. У цій секції може наводитися інформація про розробника цього класу і статус стану розроблення, а також можуть записуватися й інші загальні властивості цього класу, що мають відношення до інших класів діаграми або до стандартних елементів мови UML.
Прикладами імен класів можуть бути такі іменники, як "Співробітник", "Компанія", "Керівник", "Клієнт", "Продавець", "Менеджер", "Офіс" і багато інших, що мають безпосереднє відношення до модельованої предметної області і функціонального призначення проектованої системи.
Клас може не мати екземплярів або об'єктів. У цьому випадку він називається абстрактним класом, а для позначення його імені використовується похилий шрифт (курсив). У мові UML узгоджено , що будь-який текст, який відноситься до абстрактного елементу, записується курсивом. Ця обставина є семантичним аспектом опису відповідних елементів мови UML.
Примітка
У деяких випадках необхідно явно вказати, до якого пакету відноситься той чи інший клас. Для цієї мети використовується
396
спеціальний символ роздільник – подвійна двокрапка "::". Синтаксис рядка імені класу в цьому випадку буде таким <Ім’я_пакету>::<Ім’я_класу>. Іншими словами, перед ім'ям класу має бути явно вказане ім'я пакету, до якого його треба віднести. Наприклад, якщо визначений пакет з ім'ям "Банк", то клас "Рахунок" в цьому банку може бути записаний у вигляді: "Банк::Рахунок".
19.1.2. Атрибути класу
У другій зверху секції прямокутника класу записуються його атрибути (attributes) або властивості. У мові UML прийнята певна стандартизація запису атрибутів класу, яка підкоряється деяким синтаксичним правилам. Кожному атрибуту класу відповідає окремий рядок тексту, який складається із квантора видимості атрибута, імені атрибута, його кратності, типу значень атрибута й, можливо, його початкового значення:
<квантор видимості><ім’я атрибута>[кратність]: <тип атрибута> = <початкове значення>{рядок-властивість}
Квантор видимості може приймати одне з трьох можливих значень і, відповідно, відображається за допомогою спеціальних символів.
Символ "+" позначає атрибут із зоною видимості типу загальнодоступний (public). Атрибут із цією зоною видимості доступний або видимий з будь-якого іншого класу пакету, у якому визначена діаграма.
Символ "#" позначає атрибут із зоною видимості типу захищений (protected). Атрибут із цією зоною видимості недоступний або невидний для всіх класів, за винятком підкласів цього класу.
Символ "-" позначає атрибут із зоною видимості типу закритий (private). Атрибут із цією зоною видимості недоступний або невидний для всіх класів без винятку.
Квантор видимості може бути опущений. У цьому випадку його відсутність просто означає, що видимість атрибута не вказується. Ця ситуація відрізняється від прийнятих за замовчуванням угод у традиційних мовах програмування, коли відсутність квантора видимості трактується як public або private. Проте замість умовних графічних позначень можна записувати відповідне ключове слово: public, protected, private.
Примітка
Оскільки мова UML інваріантна щодо реалізації своїх конструкцій у конкретних мовах програмування, семантика окремих кванторів видимості не є строго фіксованою. Значення цих кванторів повинні
397
додатково уточнюватися текстом пояснення на природній мові або угодою з використання відповідних програмно-залежних синтаксичних конструкцій.
Ім'я атрибута є рядком тексту, який використовується як ідентифікатор відповідного атрибута і тому має бути унікальним в межах певного класу. Ім'я атрибута є єдиним обов'язковим елементом синтаксичного позначення атрибута.
Кратність атрибута характеризує загальна кількість конкретних атрибутів певного типу, що входять до складу окремого класу. У загальному випадку кратність записується у формі рядка тексту у квадратних дужках після імені відповідного атрибута:
[нижня_границя1 .. верхня_границя1, нижня_границя2.. верхня_границя2
..., нuжня_гpaнuцяk .. верхня_границяk],
де нижня_границя і верхня_границя є додатними цілими числами, кожна пара яких служить для позначення окремого замкнутого інтервалу цілих чисел, у якого нижня (верхня) межа дорівнює значенню нижня_границя (верхня_границя). Загалом таке умовне позначення кратності відповідає теоретико-множинному об'єднанню відповідних інтервалів. Верхньою границею може слугувати спеціальний символ "*", який означає довільне позитивне ціле число. Іншими словами, це означає необмежене зверху значення кратності відповідного атрибута.
Значення кратності з інтервалу слідують в монотонно зростаючому порядку без пропуску окремих чисел, що містяться між нижньою і верхньою границями. При цьому дотримуються такого правила: відповідні нижні і верхні границі інтервалів включаються у значення кратності. Якщо кратність задається єдиним числом, то кратність атрибута приймається рівною цьому числу. Якщо ж вказується єдиний знак "*", то це означає, що кратність атрибута може бути довільним додатним цілим числом або нулем.
Як приклад розглянемо кілька варіантів задання кратності атрибутів.
[0..1] означає, що кратність атрибута може набувати значення 0 або 1. При цьому 0 означає відсутність значення для цього атрибута.
[0..*] означає, що кратність атрибута може набувати будь-якого додатного цілого значення більшого-рівного 0. Ця кратність може бути записана коротше у вигляді простого символа - [*].
[1.:*] означає, що кратність атрибутаа може набувати будь-якого додатного цілого значення більшого-рівного 1.
[1..5] означає, що кратність атрибута може набувати будь-якого значення із чисел: 1, 2, 3, 4, 5.
398
[1..3,5,7] означає, що кратність атрибута може набувати будь-якого значення із чисел: 1, 2, 3, 5, 7.
[1..3,7.. 10] означає, що кратність атрибута може набувати будь-якого значення із чисел: 1, 2, 3, 7, 8, 9, 10.
[1..3,7..*] означає, що кратність атрибута може набувати будь-якого значення із чисел: 1, 2, 3, а також будь-якого ціле значення більшогорівного 7.
Якщо кратність атрибута не вказана, то за замовчуванням вона набуває значення, рівного 1..1, тобто саме 1.
Типом атрибута є вираз, семантика якого визначається мовою специфікації відповідної моделі. У нотації UML тип атрибута іноді визначається залежно від мови програмування, яку передбачається використовувати для реалізації певної моделі. У простому випадку тип атрибута вказується рядком тексту, що має осмислене значення в межах пакету або моделі, до якої відноситься певний клас.
Навести ряд прикладів задання імен і типів атрибутів класів.
Колір:Соlоr – тут колір є іменем атрибута, Color – іменем типу заданого атрибута. Вказаний запис може визначати традиційно використовувану RGB-модель (червоний, зелений, синій) для відображення кольору. У цьому випадку ім'я типу Color якраз і характеризує семантичну конструкцію, яка застосовується в більшості мов програмування для подання кольору.
Ім’я_співробітника [1..2] : String – тут ім’я_співробітника є іменем атрибута, який служить для подання інформації про ім'я конкретного співробітника. Тип атрибута String (Рядок) вказує на той факт, що окреме значення імені є рядком тексту з одного або двох слів (наприклад, "Кирило" або "Дмитро Іванович"). Оскільки в багатьох мовах програмування існує тип даних String, використання відповідного англомовного терміну не викликає непорозуміння у більшості програмістів. Проте, хоча в мові UML всі терміни даються англійською мовою, використання як тип атрибута Рядок в такій ситуації допускається і визначається тільки міркуваннями зручності.
Видимість:Boolean – тут видимість є іменем абстрактного атрибута), який може характеризувати наявність візуального подання відповідного класу на екрані монітора. У цьому випадку тип Boolean означає, що можливими значеннями певного атрибута є одне з двох логічних значень: істина (true) або хибність (false). При цьому значення істина може відповідати наявності графічного зображення на екрані монітора, а значення хибність – його відсутності, про що додатково вказується в тексті пояснення. Оскільки кратність атрибута видимість не вказана, вона набуває значення 1 за замовчуванням. У цій
399
ситуації англомовне ім'я типу атрибута цілком виправдане наявністю відповідного базового типу в мовах програмування. Абстрактний характер такого атрибута позначається курсивним текстом у записі цього атрибута.
Форма:Багатокутник – тут ім'я атрибута форма може характеризувати такий клас, який є геометричною фіґурою на площині. У цьому випадку тип атрибута Багатокутник вказує на той факт, що окрема геометрична фіґура може мати форму трикутника, прямокутника, ромба, п'ятикутника і будь-якого іншого багатокутника, але не кола чи еліпса. Цілком очевидно, що в такій ситуації використання відповідного англомовного терміну навряд чи доцільне, оскільки тип Багатокутник не є базовим для мов програмування.
Початкове значення служить для задання деякого початкового значення для відповідного атрибута в момент створення окремого екземпляра класу. Тут необхідно дотримуватися правила належності значення до типу конкретного атрибута. Якщо початкове значення не вказане, то значення відповідного атрибута не визначене на момент створення нового екземпляра класу. З іншого боку, конструктор відповідного об'єкту може перевизначити початкове значення у процесі виконання програми, якщо в цьому виникає необхідність.
Як приклади початкових значень атрибутів можна навести доповнені вище варіанти визначення атрибутів:
колір:Соlоr = (255, 0, 0) – в RGB-моделі кольору це відповідає чистому червоному кольору як початкове значення для певного атрибут;.
ім’я_співробітника[1..2]:String = Іван Іванович – можливо, це нетиповий випадок, який, швидше, відповідає ситуації ім’я_керівника
[2]: String = Іван Іванович;
видимість:Вооlеаn = істина – може відповідати ситуації, коли в момент створення екземпляра класу створюється видиме на екрані монітора вікно, що відповідає цьому об'єкту;
форма:Багатокутник= прямокутник – навряд чи вимагає коментарів, оскільки тут мова йде про геометричну форму створюваного об'єкту.
При визначенні атрибутів можуть бути використані дві додаткові синтаксичні конструкції – це підкреслення рядка атрибута і текст пояснення у фіґурних дужках.
Підкреслення рядка атрибута означає, що відповідний атрибут може приймати підмножину значень з деякої області значень атрибута, визначеної його типом. Ці значення можна розглядати як набір однотипних записів або масив, які в сукупності характеризують кожний об'єкт класу.
400
Наприклад, якщо деякий атрибут заданий у вигляді форма: Прямокутник, то це означатиме, що всі об'єкти цього класу можуть мати декілька різних форм, кожна з яких є прямокутником. Іншим прикладом може служити визначення атрибута у вигляді номер_рахунку:Integer, що може означати для об'єкту Співробітник наявність деякої підмножини рахунків, загальна кількість яких заздалегідь не фіксується.
Рядок-властивість служить для вказання значень атрибута, які не можуть бути змінені в програмі під час роботи з цим типом об'єктів. Фіґурні дужки якраз і позначають фіксоване значення відповідного атрибута для класу загалом, яке повинні приймати всі новостворювані екземпляри класу без винятку. Це значення береться за початкове значення атрибута, яке не може бути перевизначене в подальшому. Відсутність рядка-властивості за замовчуванням трактується так, що значення відповідного атрибута може бути змінене в програмі. Наприклад, рядок-властивість у записі атрибута заробітна_плата:Currency={$500} може служити для позначення фіксованої заробітної плати для кожного об'єкту класу "Співробітник" певної посади в деякій організації. З іншого боку, запис такого атрибута у вигляді заробітна_плата: Currency = $500 означає щось інше, а саме – при створенні нового екземпляра Співробітник (аналогія – прийом на роботу нового співробітника) для нього встановлюється за замовчуванням заробітна плата в $500. Проте для окремих співробітників можуть бути зроблені винятки як в меншу, так і в більшу сторону, що необхідно додатково передбачити в програмі.
19.1.3. Операція
У третій зверху секції прямокутника записуються операції або методи класу. Операція (operation) є деяким сервісом, що задає кожний екземпляр класу згідно з певною вимогою. Сукупність операцій характеризує функціональний аспект поведінки класу. Запис операцій класу в мові UML також стандартизований і підкоряється певним синтаксичним правилам. При цьому кожній операції класу відповідає окремий рядок, який складається з квантора видимості операції, імені операції, виразу типу значення, що повертається згідно з операцією і, можливо, рядком-властивістю даної операції:
квантор видимості><ім’я операції>(список параметрів): <вираз типу значення, що повертається >{рядок-властивість}
Квантор видимості, як і для атрибутів класу, може приймати одне з трьох можливих значень і, відповідно, відображається за допомогою спеціального символа. Символ "+" позначає операцію з областю видимості типу загальнодоступний (public). Символ "#" позначає
