GRASP
GRASP (англ. General Responsibility Assignment Software Patterns) — набір патернів (шаблонів, принципів), що дозволяють вирішувати проблеми розподілу обов'язків між різними класами. За своєю суттю, цей набір патернів більш абстрактний, ніж загально відомий каталог шаблонів від «Банди чотирьох» (GOF-шаблони).
До складу шаблонів GRASP входить 9 шаблонів:
- Information Expert
- Creator
- Low Coupling
- High Cohesion
- Controller
- Polymorphism
- Pure Fabrication
- Indirection
- Protected Variations
Відомо дев'ять GRAPS шаблонів, спочатку описаних у книзі Крейга Ларман «Застосування UML і шаблонів проектування». На відміну від звичних читачеві патернів з Банди Чотирьох, GRAPS патерни не мають вираженої структури, чіткої області застосування і конкретної розв'язуваної проблеми, а лише являють собою узагальнені підходи / рекомендації / принципи, використовувані при проектуванні дизайну системи. «Applying UML and Patterns — An Introduction to Object-Oriented Analysis and Design and Iterative Development»[1]
Предметна область
Для детальнішого розуміння читачем GRASP шаблонів, будуть описані приклади їх використання з предметної області морських вантажоперевезень. Судноплавна компанія «Навігатор +» є найбільшим постачальником послуг морських вантажоперевезень. Головний офіс компанії складається з трьох відділів: відділ по роботі з клієнтами, відділ диспетчеризації рейсів, відділ комплектації рейсів. Менеджери з відділу по роботі з клієнтами оформляють договори на доставку вантажу з пункту А в пункт В. Диспетчери з відділу диспетчеризації рейсів відстежують становище суден. Адміністратори з відділу комплектації рейсів формують вантажні рейси на підставі договорів з клієнтами.
Інформаційний експерт (Information Expert)
Шаблон інформаційний експерт є базовим і в той же час найбільш очевидним з дев'яти. Інформаційний експерт описує основоположні принципи призначення обов'язків класам і об'єктам. Відповідно до опису, інформаційним експертом (об'єктом наділеним деякими обов'язками) є об'єкт, що володіє максимумом інформацією, необхідною для виконання призначених обов'язків.
Як приклад можна розглянути підрахунок загальної кількості вантажу і його вартості як на певному рейсі, так і узагальнено для всіх рейсів компанії. Застосування шаблону інформаційний експерт підвищує зв'язність модулів і не суперечить властивості інкапсуляції.
Творець (Creator)
Клас повинен створювати екземпляри тих класів, які він може:
- Утримувати або агрегувати;
- записувати;
- використовувати;
- Ініціалізувати, маючи потрібні дані.
Так застосовується шаблон «Інформаційний експерт» (дивіться пункт №1) в питаннях створення об'єктів.
Альтернатива - шаблон «Абстрактна фабрика» (створення об'єктів концентрується в окремому класі).
Низька зв'язаність (Low Coupling) і Високе зачеплення (High Cohesion)
Мабуть в будь-якій літературі з об'єктно-орієнтованого проектування зустрічаються ці два поняття. Вважається, що будь-яка спроектована система, повинна задовольняти принципам низькою зв'язності і високого зачеплення модулів. Відповідність даним шаблонами дозволяє легко модифікувати і супроводжувати програмний код а також підвищує ступінь його повторного використання.
Розглянемо поняття міри зв'язності модулів і міри зачеплення модуля. Міра зв'язності модулів визначається кількістю інформації яку має один модуль про природу іншого. У свою чергу, міра зачеплення модуля визначається ступенем сфокусованості його обов'язків.
Варто відзначити, що існують методології, згідно з якими міри зв'язності і зачеплення можна оцінити за шкалою від 1 до 10 для конкретного випадку. Однак, в рамках даної статті вони не розглядаються.
Прикладом хорошого дизайну системи може служити набір утиліт GNU Binutils для Linux. У ньому кожна утиліта (якщо її розглядати як модуль) виконує лише мінімальні обов'язки (високе зачеплення) і майже нічого не знає про природу інших утиліт (низька зв'язність), у зв'язку з чим може бути легко замінена на аналог в деякому варіанті використання.
Стійкий до змін (Protected Variations)
Проблема модифікації системи найбільш актуальна в умовах вимог, що динамічно змінюються. Найчастіше вдається виділити так звані точки нестійкості системи, які найчастіше будуть схильні до зміни / модифікації. Тоді, сутність шаблону "стійкий до змін" полягає в усуненні точок нестійкості, шляхом визначення їх як інтерфейсів і реалізації для них різних варіантів поведінки.
Наприклад, розглянемо ситуацію розширення спектра послуг компанії «Навігатор +». Будемо вважати, що судноплавна компанія почала займатися пасажирськими перевезеннями. Для цього, реалізуємо точку стійкості системи — сутність, що перевозиться (Entity).
Контролер (Controller)
Контролер відповідає за обробку вхідних системних подій, делегуючи обов'язки по їх обробці компетентним класам. У загальному випадку, контролер реалізує один або кілька варіантів використання.
Відомо поняття зовнішнього контролера (Front Controller), який представляє всю систему в цілому (агрегує весь функціонал системи в одному класі).
Прикладом контролера є клас Administrator, який реалізує варіант використання системи адміністратором з відділу комплектації рейсів.
Використання контролерів дозволяє відокремити логіку від представлення, тим самим підвищуючи можливість повторного використання коду.
Поліморфізм (Polymorphism)
Шаблон поліморфізм дозволяє обробляти альтернативні варіанти поведінки на основі типу. При цьому, альтернативні реалізації наводяться до узагальненого інтерфейсу.
Розглянемо інтеграцію системи з зовнішніми компонентами розрахунку тарифів на перевезення вантажу. Класи LocalTarificator і WorldWideTarificator є адаптерами до відповідних зовнішніх компонентів.
Застосування шаблону поліморфізм дозволяє в майбутньому легко модифікувати систему.
Слід зауважити, що композиція, на відміну від поліморфізму, в більшості випадків, є кращою реалізацією бізнес-вимог - написаний код краще підтримується, змінюється, розширюється
Чиста вигадка (Pure Fabrication)
Існує поняття моделі програмування по предметній області, згідно з якою, кожній сутності з предметної області відповідає один або більше класів програмного середовища. При цьому, обов'язки взаємодії сутностей, як правило накладаються на них самих. Такий підхід має очевидний недолік — висока зв'язність модулів системи. Шаблон чиста вигадка дозволяє вирішити дану проблему, шляхом введення в програмне середовище додаткового класу (що не відображає реальної сутності з предметної області) і наділяє його необхідними обов'язками.
Наприклад, обов'язки по зберіганню інформації про клієнтів судноплавної компанії можна призначити вигаданому класу ClientsSaver.
Застосування шаблону чиста вигадка дозволяє дизайну системи відповідати принципам низької зв'язності і високого зачеплення.
Перенаправлення (Indirection)
Шаблон перенаправлення реалізує низьку зв'язність між класами, шляхом призначення обов'язків щодо їхньої взаємодії додатковому об'єкту — посереднику.
Прикладом даного шаблону може служити клас ClientsSaver (див. Чиста вигадка), який є проміжним шаром між сутностями клієнтів і сховищем, в якому вони будуть збережені. Крім того, контролер з тріади MVC є посередником між даними їх представленнями.
Примітки
- Larman, Craig. Applying UML and Patterns — Third Edition.