Безпека by design. Частина 3. (Основні концепції предметно-орієнтованого проектування)

6 вересня 2023 1 хвилина Автор: Lady Liberty

Предметно-Орієнтоване Проектування: Основні положення

Предметно-орієнтоване проектування (ПОП) – це методологія, яка виявляється дедалі більш важливою у сферах розробки програмного забезпечення, інженерії та бізнес-проектування. Основна ідея полягає у створенні високорівневих, абстрактних моделей, які відображають ключові аспекти деякого предметного середовища, щоб оптимізувати та покращити процеси розробки та управління. Основні Концепції ПОП: Відображення Предметності: ПОП ставить перед собою завдання створити абстрактні моделі, які точно відображають предметну область, з якою взаємодіюють користувачі або системи. Глибокий Аналіз: Центральною ідеєю є глибокий аналіз предметної області, що дозволяє створити деталізовані моделі для кращого розуміння процесів та вимог. Абстракція: ПОП застосовує абстракцію для створення моделей, які концентруються на суттєвих аспектах предметної області, ігноруючи деталі, що не є критичними.

Гнучкість: Моделі ПОП повинні бути гнучкими, легко змінюваними та розширюваними для адаптації до змінних вимог і умов. Підтримка Спільного Розуміння: ПОП допомагає створити загальне розуміння предметної області серед всіх учасників проекту, включаючи розробників, аналітиків та клієнтів. Покращення Продуктивності: Основним завданням ПОП є покращення ефективності розробки та управління проектами шляхом спрощення та оптимізації процесів. Постійна Еволюція: ПОП підтримує ідею постійного розвитку та змін, що дозволяє адаптувати моделі до нових вимог та обставин. Предметно-орієнтоване проектування – це підхід, що спрямований на покращення розробки та управління проектами, створюючи абстрактні моделі предметних областей. Це сприяє збільшенню продуктивності, якість продукту та загального розуміння серед учасників проекту. У цьому розділі. Найважливіші аспекти предметно-орієнтованого проектування з точки зору безпеки. Моделі як суворе спрощення предметної області. Об’єкти-значення, сутності та агрегати. Доменні моделі як єдина мова. Обмежені контексти та семантичні кордони.

Проектування з Абстракцією: ПОП Під Лупою

За роки, що ми розробляємо програмне забезпечення, ми знайшли багато джерел натхнення, включаючи спільні для всіх нас. Одним з найважливіших був DomainDriven Design (DDD).

DDD встановлює трохи більш високу планку для розвитку більшості систем. Ми стикалися з багатьма проектами, де головним керівним принципом було «просто змусити це працювати». Коли програмна помилка була знайдена, рішенням було додати  оператор if. Незважаючи на те, що помилки рідко генерувалися виключно локальними фрагментами коду, в проблеми ніхто не вникав і система базувалася на неповній і суперечливій моделі.

Domain-Specific Design – це підхід до розробки програмного забезпечення, при якому ми:

  • Орієнтація на основну предметну область;

  • Дослідити моделі творчої співпраці між тими, хто має досвід у цій галузі, та тими, хто розробляє програмне забезпечення;

  • Ми розмовляємо однією мовою в чітко обмеженому контексті.

DDD стверджує, що ми повинні прагнути не просто до створення працюючої системи, а до реального розуміння того, що ми насправді створюємо. Підкреслимо слово «що». DDD підкреслює глибоке розуміння предметної області, а не тільки самого рішення. З нашої точки зору, краса принципів DDD полягає в тому, що вони змушують нас переводити це розуміння в код – в результаті код використовує ту ж мову, що і проблема, яку ви вирішуєте. Ми вважаємо, що акцент на глибокому розумінні допомагає нам вдосконалюватися як розробникам. А те, що такий підхід має серйозний вплив на безпеку, стало очевидним набагато пізніше.

У цьому розділі основна увага приділяється лише деяким аспектам DDD. Це величезна і багатогранна тема, охоплення якої йде від кодування до системної інтеграції, від аналізу вимог до тестування. Він тісно пов’язаний з іншими гнучкими методологіями та процесами. Про DDD написано безліч книг і величезна кількість статей, тому всебічне обговорення такого підходу в одному розділі було б неможливо. Замість цього ми зосередимося на тих аспектах DDD, які, як показує наш досвід, можуть підвищити безпеку.

Якщо ви не знайомі з DDD, ви зможете зрозуміти цей підхід тут, що буде корисно вам у наступних розділах. Цей розділ також може служити довідником. Пізніше ми будемо використовувати різні аспекти DDD для підвищення безпеки, тому ви можете звернутися до цього матеріалу, якщо вам потрібно оновити об’єкти, значення, агрегації, контекстні карти або будь-яку іншу концепцію DDD.

Ми рекомендуємо вам уважніше розглянути цю тему, оскільки вона охоплює набагато більше, ніж просто безпеку. Хорошим початком буде міні-книга  DomainDriven Design Fast. Для початківців також підійдуть патерни, принципи та практики доменного дизайну Скотта Міллетта (Wrox, 2015). Якщо ви хочете глибоко вивчити цю тему, прочитайте основоположну книгу Еріка Еванса «Доменно-орієнтований дизайн (DDD) – У ньому ви знайдете вичерпний матеріал.

Якщо ви вже дещо знайомі з DDD, скористайтеся цією главою, щоб освіжити свої знання. І навіть якщо ви досвідчений доменно-орієнтований дизайнер, все одно читайте його, так як він зачіпає аспекти, які хотілося б підкреслити – вони будуть використовуватися в майбутньому для підвищення безпеки. Майте на увазі також, що деякі ідеї будуть представлені в кілька стислому вигляді і можуть здатися трохи спотвореними. Ми не претендуємо на повноту, а лише прагнемо надати вам матеріал, якого буде достатньо для обговорення безпеки.

Ми розглянемо  моделі доменів, які лежать в основі розробки системи в стилі DDD. Моделі доменів забезпечують однозначну, сувору основу для опису функцій системи. Це представляє певний інтерес з точки зору безпеки. Описуючи обов’язки системи, ви також отримуєте чудову можливість визначити, чого вона робити не повинна.

При моделюванні та реалізації моделей у коді корисно мати під рукою деякі будівельні блоки. Моделі доменів, як правило, базуються на об’єктах, значеннях та сутностях. Більші структури, як правило, представлені у вигляді агрегатів. Використання цих елементів зробить ваш код більш суворим і менш схильним до вразливостей.

Якщо відійти від окремої системи і розглянути рівень інтеграції, то DDD надає такі інструменти, як обмежені контексти і контекстні карти. З їх допомогою вам буде простіше забезпечити безпеку і тісну інтеграцію між декількома системами. Дизайн для конкретного домену базується на строгих моделях доменів, тому спочатку ми покажемо вам, як їх створити, щоб ви могли використовувати їх, щоб добре зрозуміти проблему, яку може вирішити ваше програмне забезпечення.

Моделі як засіб забезпечення більш глибокого розуміння

Спочатку пояснимо, що таке моделі, що стоять за  DDD. У системній розробці слово «модель» може означати безліч різних речей: блок-схеми в UML, спосіб зберігання інформації в таблицях баз даних і так далі. У DDD модель описує основні бізнес-аспекти, з якими ви маєте справу, як певний набір понять. Навіщо потрібні такі моделі і як вони повинні виглядати?

Всі ми знаємо, що не існує такого поняття, як панацея, і ДДД не виняток. Щоб нікого не вводити в оману, завжди необхідно відзначати ті випадки, коли  методика або методика не дає істотних переваг, і повинні бути вказані обставини, для яких вона ідеальна. Якщо ви розробляєте мережевий маршрутизатор або систему управління багажем, зовнішні обставини можуть сильно відрізнятися. У першому випадку ДДД мало допоможе,  А в другому зможе принести чималу користь.

У прикладі мережевого маршрутизатора найважливішою проблемою є технічна проблема – досягнення досить високої пропускної здатності вводу-виводу і досить низької затримки, що є зовсім непростим завданням. Якщо ви не впораєтеся з ним, то в результаті отримаєте товар, який ніхто не захоче купувати. Продуктивність мережі – найважливіша характеристика роутера. DDD може допомогти вам з моделюванням черг пакетів і таблиць маршрутизації, але не з пропускною здатністю або затримкою.

Для порівняння розглянемо приклад системи управління багажем в аеропорту. Його технічна реалізація буде використовувати ті ж бази даних, черги повідомлень і фреймворки графічного інтерфейсу, що і більшість інших систем. Звичайно, все це вносить чималі складності, але, швидше за все, основна проблема буде в іншому. Ваша система повинна вміти описувати проходження багажу від пункту реєстрації до літака по стрічках конвеєрів і навантажувальних машин. Якщо цей опис виявиться невірним, багаж може запізнитися на потрібний рейс або полетіти не в тому напрямку. Це може дратувати пасажирів і завдати репутаційних і фінансових збитків компанії. Що ще гірше, на карту поставлені важливі аспекти безпеки. Зі зрозумілих причин багаж допускається в літак тільки в тому випадку, якщо його власник вже там. Якщо багаж вже був зареєстрований, а пасажир не з’явився, система повинна подбати про вивантаження відповідних валіз. Якщо він спроектований бездоганно, існує ризик того, що він може бути змушений завантажити валізу на певний рейс або залишити його на борту, навіть якщо його слід розвантажити – іноді це може мати серйозні наслідки для безпеки.

Якщо вам не вдасться отримати глибоке і чітке розуміння того, як обробляється багаж, ви створите несправну систему. Але найгірше те, що це може бути шкідливо для компанії і потенційно небезпечно для клієнтів. Може дійти до того, що система виявиться абсолютно марною і аеропорт швидше закриють, ніж приймуть її в експлуатацію. Це не гіпотетичний приклад: відкриття аеропорту Денвера,  Який повинен був відбутися в 1990 році, був відкладений на півтора року через недоробки в системі управління багажем, що призвело до великих фінансових втрат. У таких ситуаціях розуміння та моделювання зони управління багажем має бути вашою першочерговою турботою. І було б помилкою витрачати час на оптимізацію пулу підключень в базі даних. У цьому прикладі предметною областю є критична складність завдання.

DDD найкраще працює, коли система має справу з предметною областю, яку важко зрозуміти. У таких ситуаціях найбільш актуальними завданнями є розуміння складності предметної області і її моделювання. Якщо ви не зможете вникнути у всі тонкощі різних технічних аспектів, ваша система виявиться не такою корисною, як хотілося б. Але якщо ви не можете зрозуміти складнощі предметної області,  Тоді ви отримаєте систему, яка робить не те, що потрібно. У цьому сенсі предметна область має  критичну складність.

З нашого досвіду, більшість бізнес-додатків потрапляють в цю категорію. Розуміння предметної області і створення відповідної моделі є основою для вирішення завдань бізнес-логіки.

Вам може здатися, що предметна область – це щось нетехнічне. Але це не так. Іноді критична складність пов’язана з предметною областю, а сама область технічна. Уявіть, що ви пишете оптимізуючий компілятор. Він перетворює вихідний код в добре оптимізований машинний код, який може бути виконаний, при цьому він використовує локальні оптимізації, усуває «мертвий» код, розширює підвирази під час компіляції і т. д. Складність тут полягає не в поліпшенні продуктивності читання/запису файлів, а в застосуванні всіх цих оптимізацій таким чином, щоб отримана програма робила те, що вказано у вихідному коді. Основні зусилля повинні бути спрямовані на суворе подання вихідного коду і виконання перетворень, щоб оптимізована програма не змінила свою суть. Тут критична складність специфічна для домену, але сам домен технічний!

Тепер спробуємо розібратися, яке відношення це має до безпеки. Вам буде нелегко отримати всі знання, необхідні для того, щоб ваша система поводилася належним чином у будь-якій можливій ситуації. З огляду на всі дивні випадки, які можуть виникнути, це завдання буде досить складним навіть в тому випадку, якщо працювати зі звичайними, безпечними даними. Але все стане ще складнішим, якщо вам потрібно бути стійким до шкідливих даних. Хтось може спробувати атакувати вашу систему, надіславши їй вигадливі дані, щоб обдурити її, щоб зробити щось неприємне. І навіть в цьому випадку система повинна реагувати правильним і безпечним чином. Ми вже бачили це на прикладі книжкового інтернет-магазину в розділі 2. Жодна звичайна бізнес-процедура не може привести до додавання антикнижки в кількості -1 в кошик. Однак недобросовісний замовник може зробити це для того, щоб маніпулювати системою (в цьому випадку знизити загальну вартість замовлення).

Як показує наш досвід, для забезпечення безпеки основну увагу слід приділяти побудові доменних моделей. Побічним ефектом такого підходу буде те, що вдасться уникнути багатьох проблем безпеки, особливо тих, що стосуються ділової доброчесності. Крім того, моделі доменів певною мірою захищають ваш код від деяких технічних атак.

Вам потрібні доменні моделі, що сприяють стабільному і безпечному розвитку.

Ефективна модель повинна:

  • Бути простий, щоб ви могли зосередитися на ключових моментах;

  • Бути суворою, щоб служити основою для написання коду;

  • Забезпечувати глибоке розуміння, щоб зробити систему по-справжньому корисною;

  • Бути кращим вибором з прагматичної точки зору;

  • Надавати мову, яку можна використовувати під час обговорення системи.

ДДД не панацея: корисність такого підходу залежить від контексту. Бувають ситуації, в яких не варто загострювати увагу на моделюванні домену. Наприклад, якщо ви пишете програмне забезпечення для мережевого маршрутизатора, найважливішим аспектом для вас буде пропускна здатність вводу-виводу. В даному випадку критична складність криється в технічній площині. Але навіть тут необхідно задуматися про те, чи не створює неповна модель домену ризики безпеки.

ПОРАДА. Критична складність існує завжди. Потрібно визначити, чи відноситься це до технічних аспектів або до предметної області.

На наш погляд, основною перевагою предметного моделювання є те, що воно стимулює більш глибоке вивчення предмета, що є незамінним. Освоїти жаргон професіоналів бізнесу не так вже й складно, і можна за допомогою цієї ж мови скласти список вимог, який на перший погляд виглядає пристойно. Але якщо глибокого розуміння області немає, в неї можуть закрастися непорозуміння, нестиковки і логічні лазівки. Ці недоліки завадять вам створити надійну систему, яка коректно поведе себе в нестандартних ситуаціях, а в гіршому випадку стане причиною вразливостей безпеки. Працюючи над моделлю предметної області з експертами, можна багато чому навчитися.

Модель є спрощеною версією реальності

Модель – це спрощена версія реальності, з якої прибирається все, що вам не потрібно. Наприклад, коли ви реєструєте свій багаж в аеропорту, системі не потрібно знати розмір вашого взуття. А ось інформація про вагу валізи може стати в нагоді. Щоб вам було простіше зрозуміти і реалізувати систему, модель повинна містити тільки ту інформацію, яка вас цікавить, наприклад, вага багажу, але не розмір взуття пасажира.

Слід розуміти, що модель – це не діаграма. Хоча в багатьох інших контекстах модель може означати діаграму певного типу, як у випадку з моделями відносин при проектуванні баз даних або діаграмами класів в UML. Ці діаграми є уявленнями моделей, але самі моделі  описують спрощене розуміння реальності на концептуальному рівні.

ПРИМІТКА. Модель – це не діаграма, а певний набір абстракцій.

У DDD термін «модель» використовується майже в тому ж значенні, що і в моделюванні залізничного транспорту. При виготовленні моделей поїздів деяким аспектам дійсності приділяється велика увага, а іншим і зовсім ігнорується (рис. 3.1). Розуміння того, які деталі повинні бути реалістичними, а які можуть бути спотворені, є ключем до створення як іграшкових поїздів, так і моделей доменів.

На рис. 3.1 Показана модель поїзда. Він схожий на поїзд і рухається по рейках, але справжнім поїздом його назвати не можна. Ми вважаємо його моделлю, оскільки він зберігає деякі важливі атрибути, ігноруючи інші. Давайте перерахуємо параметри, загальні для іграшкових і справжніх поїздів.

  • Колір. Ми вважаємо, що модель певного поїзда повинна мати той самий колір, що й оригінал.

  • Відносні розміри. Ми очікуємо, що пропорції буде дотримано. Якщо насправді висота дверей вдвічі більше ширини, те саме співвідношення має бути і в моделі.

  • Форма. Ми очікуємо, що модель поїзда та її деталі матимуть ту саму форму, що реальний поїзд.

  • Рух. Ми очікуємо, що модель поїзда рухатиметься рейками так само як це робить справжній поїзд.

Назвемо також деякі атрибути моделі, точне відтворення яких ми вважаємо необов’язковим.

  • Матеріал. Нічого страшного, якщо модель зроблена з пластику чи жерсті, а оригінал – з інших матеріалів.

  • Абсолютний розмір. Якщо справжні вагони мають довжину 30 метрів, то у моделі вони можуть бути набагато меншими, і це нормально.

  • Вага. Модель набагато легша, що цілком очікувано.

  • Механізм потягу. У моделі немає парового двигуна, вона працює на електриці.

  • Вигин рейок. У моделі рейки можуть згинатися набагато сильніше, ніж у реальності, і це припустимо

Дивно, але знайти відмінності між іграшковим поїздом і справжнім поїздом набагато простіше, ніж подібності. Проте ми переконані, що дана модель поїзда правильна. Їй явно вдалося увібрати в себе основні аспекти того, що ми маємо на увазі під поїздом.

Колір, відносний розмір і рух – цього повинно бути достатньо, щоб зрозуміти, що перед нами поїзд. Це три необхідні атрибути: якщо їх не дотримуються в моделі, ми не будемо прикидатися і називати його поїздом. Якщо модель не відповідає якимось іншим вимогам, ми можемо її проігнорувати.

ПРИМІТКА. Модель – це спрощена версія реальності, яку ми все ще можемо сприймати як правильне уявлення про реальну річ.

На цьому ми завершуємо нашу екскурсію в світ іграшок. Основна ідея, яку слід винести з цієї подорожі, полягає в тому, що модель – це спрощене уявлення чогось реального. Це стосується і моделей, які ми використовуємо при розробці систем. При моделюван

Модель є спрощенням, але вона все одно повинна бути досить загальною, щоб охопити різні варіації, які вам цікаві. У прикладі допускаються різні імена, вік і розміри взуття, а також наявність або відсутність домашньої тварини. Все це може проявитися в моделі. Ми не розрізняємо людей різного зросту і не звертаємо уваги на їх зачіску (рис. 3.3).

Цю модель можна представити безліччю різних способів: використовувати звичайний текст або проілюструвати її різного роду діаграмами (наприклад, порівняти рис. 3.2 і 3.4). А також застосувати код (псевдокод або реальну мову програмування). Важливо те, що жоден з цих поглядів не є моделлю. Зокрема, діаграми класів часто приймають за модель, але моделі як такі не ідентичні своїм уявленням. Модель – це концептуальне розуміння того, що ви вважаєте важливим у процесі моделювання – у цьому випадку ім’я, вік, розмір взуття та домашня тварина.

Основна перевага використання моделей як дуже спрощеної версії реальності полягає в тому, що прості моделі легше зробити строгими. Пізніше, коли ви будете створювати програмне забезпечення з них, це буде важливо.

Моделі повинні бути суворими

Модель предметної області – це не просто спрощена версія реальності: недолік деталізації компенсується додатковою строгістю. Слово «строгість» в даному випадку вживається в математичному сенсі і означає «точність»: поняття, атрибути, установки і поведінку повинні бути однозначними.

Люди – дуже складні істоти з багатьма атрибутами та стосунками. Вибравши зосередитися на імені, віці, розмірі взуття та домашніх тварин, ви втратили багато деталей. Але замість цього у вас є точне визначення того, що ви маєте на увазі під людиною, і завдяки цій точності ви можете представити цю сутність в програмному коді. Потрібно докласти чимало зусиль, щоб визначити, якими деталями можна пожертвувати заради точності. І якщо ви хочете зробити це правильно, вам доведеться звернутися до людей з глибоким розумінням предметної області.

Написання програмного забезпечення передбачає співпрацю між професіоналами двох різних профілів, які повинні продуктивно взаємодіяти. Йдеться про професіоналів бізнесу і розробників. Кожна партія має особливі потреби, задоволення яких є запорукою створення чудового продукту. Професіоналам бізнесу потрібно мати справу з термінологією, до якої вони звикли, а не з якоюсь технічною абракадаброю. Якщо вони не визнають свою власну предметну область, це буде означати, що ви їх підвели.

Кілька термінів:

  • предметна область (домен) – та частина реального світу, в якій щось відбувається (наприклад, зона управління багажем);

  • Модель домену – це відфільтрована версія предметної області, в якій кожне поняття має певне значення.

  • Код – це закодована версія моделі предметної області, написана на мові програмування.

Просто мати знайомі слова в інтерфейсі користувача або в заголовках друкованих звітів недостатньо. Система повинна вести себе таким чином, щоб професіонали бізнесу вважали її логічною, послідовною і зрозумілою. Для цього доменна модель повинна бути строгою. Якщо модель слабка і містить двозначності, різні частини системи можуть вести себе по-різному.

Наприклад, на екрані в пункті реєстрації може з’явитися «кількість валіз», на виході на посадку – «кількість багажу», а на планшетах навантажувача – «багаж». Ситуація може ускладнитися, якщо одні з цих понять враховують ручну поклажу, а інші ні. Коли співробітники аеропорту спілкуються між собою, кожен з них повинен пам’ятати, на який екран дивиться його співрозмовник і чи варто додавати/віднімати ручну поклажу. Іноді виникають непорозуміння і багаж губиться. Система підводить компанію і виглядає нелогічно навіть для фахівців в предметній області.

Збентеження також можуть виникати, коли модель послідовна з точки зору термінології, але має занадто м’які обмеження і відносини. У багатьох випадках це результат використання стандартної системи, адаптованої до предметної області; Так, наприклад, зазвичай використовуються продукти ERP (enterprise resource planning).

У 1940-х і 1950-х роках комп’ютери вперше були використані в комерційних цілях: вони використовувалися для планування використання пристроїв і сировини у виробництві, що стало великим кроком вперед у порівнянні з паперовою тяганиною і ручними процедурами. У 1980-х  роках планування  матеріальних потреб (MRP) еволюціонувало в планування ресурсів  (планування виробничих ресурсів, іноді скорочено MRP II) і стали включати фінанси, персонал, маркетинг та інші так звані ресурси. Однак у початковій предметній області ресурси з матеріального рахунку-фактури все ще використовувалися для виробництва продукції. І, оскільки існують різні підприємства, ці MRP мали дуже гнучку конфігурацію.

У 1990-х роках ці процеси еволюціонували в ERP-системи і стали використовуватися для планування роботи цілих підприємств, а щоб вони могли працювати на будь-якому підприємстві будь-якої галузі, їх конфігурація була зроблена ще більш гнучкою. Їх часто описували і продавали як стандартні системи, які можна було налаштувати для роботи в будь-якій предметній області. Однак це були однакові системи управління матеріалами. Цей напрямок бізнесу успішно продавало такі системи для обробки скарг клієнтів, поліцейських розслідувань та інших абсолютно різних сфер діяльності. На жаль, успішний продаж системи не означала, що вона принесла якусь користь. Якщо ви хочете налаштувати систему управління матеріалами для проведення поліцейських розслідувань, вам потрібні дуже неочевидні абстракції: поліцейський може бути представлений як пристрій, а протокол про пограбування – як купа сировини, яке обробляється пристроєм (поліцією) в ході розслідування.

Щоб втиснути одну предметну область в іншу, потрібно бути менш конкретним і точним. Результатом часто є загальна система управління об’єктами, в якій будь-яка сутність є об’єктом. Призначений для користувача інтерфейс дозволяє оновлювати атрибути об’єктів, але така узагальнена модель не несе багато інформації про те, що ці об’єкти насправді представляють. Часто можна вказати будь-яку комбінацію атрибутів і відносин.

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

ПРИМІТКА. Хороша система піклується про потреби як професіоналів бізнесу, так і розробників. Вона повинна відповідати професійним потребам обох цих груп.

Очевидно, що варто звернути увагу на професіоналів своєї справи. Їм необхідно працювати в знайомій предметній області, тому потрібно підбирати звичну для них термінологію. Якщо цього досягти не вдасться, це буде великою помилкою. Так само велика, як і нездатність задовольнити потреби інших фахівців з розвитку.

Зрештою, наші обов’язки як розробників зводяться до написання коду. І це математично строгий код — він вказує комп’ютеру, що робити на основі даних, які ми маємо, відповідно до правил, які ми написали. Саме тому потрібна строгість. І отримати його можна або з бесід з профільними експертами, або заповнивши прогалини освіченими здогадками.

Якщо ми скажемо, що більшість людей не мають більше однієї домашньої тварини, цього недостатньо. Розробники повинні знати, чи обмежена кількість домашніх тварин лише одним. Це той аспект нашої професії, який вимагає певної сміливості. Потрібно задавати питання, щоб модель вийшла строгою і однозначною. Якщо ви запитаєте, чи може бути більше одного вихованця, відповідь може бути такою: «О, ну, це дуже рідкісне явище». В результаті можна або дозволити вказувати список тварин, або задовольнятися тим, що тварин може бути тільки одне. У першому випадку система може ускладнитися і рано чи пізно зіткнеться з якоюсь незвичайною комбінацією атрибутів. У другому випадку вам заборонять перераховувати більше одного вихованця і через кілька місяців ви відчуєте обурення покупців (які, можливо, дістали вас при покупці іншої фірми), у яких їх два і більше. Що ще гірше, бізнес-професіонали можуть зробити з вас цапа-відбувайла, лукаво сказавши: «Ми сказали вам, що це може статися», навіть якщо ви зробили розумне припущення, щоб не надто ускладнювати систему. Потрібно вміти приймати рішення, щоб рухати розвиток вперед.

Щоб не потрапити в цю пастку, слід активно цікавитися, якою має бути модель: «Чи варто допускати додавання декількох вихованців або краще обмежитися одним?» Якщо ваша система не підтримує кілька домашніх тварин, їх доведеться обробляти за допомогою окремої ручної процедури. Але підтримка великої різноманітності також має свою ціну. Заманливо мати можливість працювати з все більш загальними моделями, але рано чи пізно всі ваші сутності будуть пов’язані один з одним відносинами багато-до-багатьох. У довгостроковій перспективі ні до чого доброго це не приведе. Наслідки використання загальної моделі важко передбачити і зрозуміти.

Уявіть, що у вас є функція, яка дозволяє клієнтам обмінюватися домашніми тваринами. Якщо одночасно у однієї людини може бути кілька чотириногих, доведеться переосмислити таку можливість. Чи означає це, що клієнт А отримує всіх тварин клієнта Б і навпаки? Або тварини обмінюються по одному? Якщо ви не відображаєте сферу бізнесу в моделі, ви можете підвести професіоналів бізнесу. Якщо створити недостатньо сувору модель, можна підвести розробників.

ПРИМІТКА. Хороша модель повинна відображати сферу бізнесу і при цьому бути суворою. Наявність строгої моделі означає, що її в кінцевому підсумку можна використовувати як основу для написання коду.

Коли ви розробляєте програмне забезпечення, ви приймаєте схожі рішення – ви створюєте просте уявлення про складне явище. Розглянемо приклад об’єктно-орієнтованого коду, який зазвичай використовується в шкільних підручниках.

Це дуже поверхнева характеристика людини, яка ігнорує безліч атрибутів і відносин:

Тут немає величезної кількості властивостей і операцій, характерних для людини. Модель зводиться до чотирьох атрибутів, важливих в конкретному контексті. Вона має мету – сферу поведінки, яку ви хочете описати. На перший погляд, відмова від деталей робить систему біднішою, але натомість ми отримуємо щось дуже важливе – вміння бути точним.

Людина – складна  істота зі складними зв’язками. Але в нашій моделі клас Person  – це щось з ім’ям, віком, розміром взуття, домашнім улюбленцем і можливістю старіти. І все. Саме це ми маємо на увазі під терміном «людина». Втрачаючи деталі, ми отримуємо точність.

Моделі включають глибоке розуміння предметної області

Звичайно, попередній приклад моделювання людини виявився до смішного простим. Реальні проблеми набагато складніші, як і у випадку з обробкою багажу в аеропорту. Чітке розуміння того, що саме охоплює модель домену, не так просто, як багато хто може подумати. Насправді, знання, які вам потрібно охопити, навіть глибші, ніж те, що експерти використовують у своїй повсякденній роботі при вирішенні окремих проблем. Причина цього в тому, що розуміння повинно вистачити вам не просто для роботи в конкретній предметній області, а для створення комп’ютерної системи.

Давайте порівняємо це з їздою на велосипеді.

Більшість з нас є фахівцями з велоспорту в тому сенсі, що ми не думаємо про кожен свій крок. У цьому легко переконатися, якщо їздити на велосипеді в складних умовах: по нерівних дорогах, у вітряну погоду і, можливо, навіть з великим пакетом в одній руці. Потрібна майстерність. Порівняйте це з труднощами, з якими стикається дитина, яка тільки вчиться кататися по гладкій поверхні в сонячний літній день. Знання фахівців предметної області можна порівняти з таким умінням – вони розуміють свою сферу діяльності. Наприклад, фахівець з доставки знає, як будувати маршрути для вантажних контейнерів навіть в складних умовах, наприклад, коли контейнер був помилково вивантажений з корабля і найближчим часом не очікується ніяких морських походів в тому ж напрямку. Спеціаліст в предметній області здатний залагоджувати навіть складні ситуації, розглядаючи їх по черзі.

На жаль, написання програмної системи вимагає ще більш глибокого розуміння. Ви не можете бути «на місці», оцінюючи виникаючі проблеми і імпровізуючи для їх вирішення – все це розкіш, яка вам недоступна. Ви пишете програму, яка повинна робити все це без вашої присутності. Більш влучною аналогією тут є не навчання дитини їзді на велосипеді, а створення робота-велосипедиста.

При розробці такого робота розуміння велоспорту має бути набагато глибше, ніж у більшості фахівців, включаючи професійних велокур’єрів або тих, хто займається велокросом. Наприклад, як повернути праворуч, коли ви їдете на велосипеді? Подумайте про це кілька секунд – ви, напевно, робили це тисячу разів. Більшість людей без коливань відповість: «Я потягну за праве кермо». На жаль,  За рахунок відцентрової сили ви нахилитеся вліво і впадете на асфальт.

Насправді ви підсвідомо повертаєте кермо вліво, що змушує вас на мить відхилятися вправо. Через кілька мілісекунд нахил досягне відповідного кута, після чого ви повернете кермо вправо і зробите маневр. Нахил вправо повинен бути саме таким, щоб компенсувати відцентрову силу, це дозволить виконати безпечний і стійкий поворот (рис. 3.5). Ви робите це, не замислюючись і не розбираючись у всіх тонкощах кінематики. Якщо ви хочете створити робота-велосипедиста, це рівень, на якому ви повинні освоїти цю тему.

Історія робота приносить як погані, так і хороші новини. Погана новина полягає в тому, що в голові фахівця з предметних питань немає готової, реальної моделі.  Ви не зможете отримати від нього відповіді на всі свої запитання.

Але хороша новина полягає в тому, що співпраця над моделлю з експертами з предметних питань може бути веселою та корисною. Це процес поступового дослідження різних моделей з вибором тієї, яка підходить для вирішення існуючих завдань.

Модель не створена, а обрана

Один з поширених міфів про моделювання, якого дотримуються багато, передбачає наявність ідеальної моделі в голові фахівця предметної області. Справа не в цьому. Створення моделі передбачає усвідомлений вибір з безлічі варіантів: модель повинна відповідати вашим потребам, які визначають її призначення.

ПРИМІТКА. Немає однієї реальної моделі, є тільки варіанти. Вибирайте той, який відповідає вашим цілям.

Люди, які практикують ДДД, іноді використовують вираз «модель дистиляції». Давайте на хвилинку порівняємо себе з виробниками віскі. Щоб трохи спростити, виробництво віскі починається з великої кількості заграв сусла, непридатного для пиття. Сусло нагрівається і збираються пари. Вихідний продукт, що містить ацетон, виливається. Середня частина в основному містить спирт і трохи води з натуральним ароматизатором. Вона покинута. В останній частині трохи спирту і велика кількість води, смак її не найприємніший. Його теж викидають. Залишилося лише те, що ми називаємо віскі. Ваше ставлення до цього напою і переваги можуть відрізнятися, але основна думка повинна бути ясною. В процесі дистиляції ми свідомо зберігаємо деякі частини і відкидаємо ті, які нам не потрібні. Точно так же, переганяючи модель, ви позбавляєтеся від одних аспектів реальності і залишаєте інші.

Важливим тут є те, що перегонка може здійснюватися різними способами. У нас є вибір. Ми навмисно залишаємо середню частину, так як наше завдання – отримати міцний напій зі специфічним смаком. Ми намагаємося перегнати те, що приємно споживати. Мета визначає спосіб перегонки.

Однак виробник міг би приймати інші рішення, якби у нього була інша задача. Якби він хотів отримати ацетон, процес виглядав би інакше. Перша частина була б збережена, а все інше було б відкинуто. Точно так само ви можете дистилювати різні моделі з однієї реальності залежно від того, для чого ви збираєтеся їх використовувати.

Наша модель, яка описує людину з ім’ям, віком, розміром взуття та домашнім улюбленцем, є лише одним із варіантів. Інша модель може описувати людину за його датою і місцем народження, іменами матері і батька. Не можна сказати, що один з цих підходів більш правильний, ніж інший (рис. 3.6). Вони різні і підходять для різних цілей. Якщо вести реєстр членів кінологічного клубу, перша модель буде явно краще. Але якщо ви досліджуєте, куди емігрували різні члени сім’ї, другий варіант відмінно підійде, і перший виявиться марним.

В процесі моделювання намагайтеся вибирати різні моделі, які виражають вашу предметну область. Спробуйте знайти три моделі і порівняйте, наскільки добре вони підходять під ваші завдання. Пошук оптимального варіанту важливий, так як дозволяє ефективно і однозначно міркувати про предметну область. Хороша модель робить мову.

Модель формує єдину мову

Цікавим аспектом моделювання є те, що воно формує мову, на якій ми міркуємо про систему. Для початку слід зазначити, що коли фахівці домену спілкуються між собою, вони говорять на своїй  мові. Це доменна мова  (або доменна мова). В англомовній країні це може звучати як англійська. Але він має ледь помітні особливості. Є досить багато слів,  які ніколи не будуть в ньому використовуватися (наприклад, ви навряд чи почуєте слово «кервель» при обговоренні бухгалтерського обліку). І навпаки, експерти використовують специфічні терміни та ідіоми, яких немає в розмовній мові (наприклад, «пам’ятки»). Фахівці спілкуються мовою, що дозволяє налагодити ефективну взаємодію.

Подумайте на мить про те, якою мовою говорять розробники мовних систем. При спілкуванні один з одним ми легко можемо перекидатися термінами, які звучать для нас логічно, але будуть абсолютно незрозумілі людям, що працюють в інших сферах: наприклад, ми можемо створити «пул зв’язків» або зробити з чогось «стратегію». Фахівці з фінансів, логістики або охорони здоров’я також мають свій жаргон.

Якщо ви розробляєте логістичну систему, здається логічним взяти термінологію з логістики і закодувати її в програмну систему. Це чудова ідея, але, на жаль, погана ідея. Мова, яку використовують експерти в цій галузі, не є логічно послідовною. І зовсім не через те, що вони навмисно недбало поводяться зі своєю термінологією. Ми, розробники, теж часто грішимо цим. Прослухати розмову між будь-якими двома досвідченими програмістами,  І ви помітите, що вони використовують слова «об’єкт», «екземпляр» і «клас» як взаємозамінні, хоча це неправда. Ви це знаєте, тому що при знайомстві з об’єктно-орієнтованим програмуванням завжди є чіткий поділ між об’єктами і класами. Але експерти, які розмовляють між собою, можуть бути недбалими, адже вони розуміють один одного і дискусія насправді йде на більш високому рівні.

Було б чудово, якби під час розробки логістичної системи ви могли створити мову, на якому можна було б обговорювати свою роботу з повним взаєморозумінням. Ось для чого потрібна модель. Якщо ви разом з фахівцями з логістики вирішите, що  «плече» означає перевезення з одного місця в інше за допомогою одного і того ж транспортного засобу, а «комплектувати  плече» – розвантаження вантажу в пункті призначення,  Тоді ви можете пояснити себе за допомогою цих термінів. Фраза «Якщо два транспорти завершують руку в одній доці, вони можуть виконувати спільне транспортування на наступній нозі» буде розумітися однозначно, щоб можна було реалізувати відповідний функціонал (рис. 3.7).

Щоб використовувати термінологію DDD, при обговоренні системи ми хочемо перетворити модель в єдину мову. «Єдиний» в даному випадку означає, що цю термінологію слід використовувати всюди, де йде розмова про систему (рис. 3.8). Ті самі терміни слід використовувати в інтерфейсі користувача, посібниках з інструкціями, вимогах (або історіях користувачів), коді та таблицях бази даних

Уявімо, що одне і те ж значення  називається в  інтерфейсі користувача кількістю, сума викликається в  керівництві, а стовпець бази даних – Volume, що просто нелогічно. Цілеспрямоване використання спільної мови в різних сферах допомагає знаходити неясності, які згодом можуть проявлятися у вигляді дефектів програмного забезпечення або дірок в безпеці.

Звичайно, слід зазначити, що модель, призначена для постійного зберігання, може трохи відрізнятися від концептуальної моделі. Наприклад, може знадобитися розділити поняття на різні таблиці або об’єднати таблиці чи синтетичні ключі, які не є частиною концептуальної моделі. Аналогічно на етапі реалізації класи в коді можуть дещо відрізнятися від термінів, що використовуються в концептуальній моделі. Однак ви описуєте ту саму інформацію, тому вам слід якомога більше використовувати ту саму мову при іменуванні ваших конструкцій (класів або таблиць бази даних).

Це не означає, що тепер потрібно ревно стежити за чистотою мови. Модель предметної області – це єдина мова для обговорення системи. Вчені домену все ще можуть використовувати неоднозначні поняття при спілкуванні один з одним, так само, як розробники можуть бути необережними, коли мова йде про об’єкти і класи.

Точність однієї мови важлива, коли ви говорите про систему. Це особливо важливо при спілкуванні між професіоналами бізнесу і розробниками, коли ризик непорозуміння максимально високий. У таких ситуаціях слід наполягати на використанні єдиної мови.

Контекст мови має певні межі. У DDD це називається обмеженим контекстом моделі. В її межах кожен термін, який використовується в моделі, має  чітко визначене значення, але поза ним ці значення можуть бути абсолютно різними. Ми детально обговоримо обмежені контексти далі в цьому розділі. Глибоко розуміючи модель та її призначення, ви можете взяти на себе більш приземлені аспекти. Модель потрібно якось впроваджувати,  І стандартні комплектуючі нам в цьому допоможуть.

Складові частини моделі

Щоб відобразити модель у коді, знадобиться набір стандартних блоків. Вони повинні бути чітко визначені, так як потрібні для організації і структурування складних моделей. Це фреймворк, який дозволяє чітко відокремити логіку домену від решти коду і допомагає розібратися з технічними аспектами процесу.

У DDD будівельними блоками, які представляють для нас особливий інтерес, є сутності, об’єкти цінності та агрегати (рисунок 3.9). Вони нас цікавлять тому, що, використовуючи їх певним чином, можна закласти основу безпеки програмного забезпечення.

Якщо ви зрозумієте ці будівельні блоки, вам буде легше зрозуміти концепції, які обговорюються далі в книзі. У цьому розділі ви дізнаєтеся значення кожного з цих термінів, їх характеристики та спосіб їх використання.

Юридичні особи

Кожна частина моделі предметної області має певні характеристики і значення. Сутності – це модельні елементи, які мають різні властивості. Саме це робить їх особливими.

  • По суті є ідентифікатор, який її визначає та відрізняє від інших сутностей.

  • Цей ідентифікатор не змінюється протягом усього життєвого циклу сутності.

  • Сутність містить інші об’єкти, у тому числі інші сутності чи об’єкти значення.

  • Сутність відповідає за координацію операцій з об’єктами, що їй належать.

Це означає, що для того, щоб з’ясувати, чи однакові дві сутності, потрібно перевірити їхні ідентифікатори, а не атрибути. Це ідентифікатор, який визначає сутність, незалежно від її атрибутів. Ідентифікатор ніколи не змінюється. Протягом усього свого життєвого циклу сутність може змінюватися і набувати безліч різних атрибутів і аспектів поведінки, але її ідентифікатор завжди залишається незмінним.

Візьмемо, наприклад, машину. В процесі експлуатації багато його атрибути можуть змінюватися. У нього може з’явитися новий власник, його можна перефарбувати, встановити нові запчастини. Але це все той же автомобіль. При цьому ідентифікатором транспортного засобу може бути унікальний ідентифікаційний номер транспортного засобу (VIN), який складається з 17 символів і присвоюється йому при виготовленні.

Іноді ідентифікатор сутності є унікальним всередині системи, а іноді його унікальність обмежена певною областю. У деяких випадках ідентифікатор сутності може бути унікальним і актуальним навіть за межами поточної системи. Він також використовується для позначення сутності з інших частин моделі.

Ще одна важлива особливість сутності полягає в тому, що вона відповідає за координацію об’єктів, які їй належать, не тільки за забезпечення узгодженості, але і за підтримку її внутрішніх інваріантів. Здатність точно ідентифікувати інформацію та координувати / контролювати поведінку дуже важлива, якщо ви не хочете, щоб недоліки безпеки проникли у ваш код. У наступних розділах ви побачите, що саме ця функція робить сутності важливим інструментом для написання безпечного коду.

Безперервність ідентифікатора

Іноді об’єкт домену визначається його атрибутами, але буває, що вони змінюються з плином часу, не впливаючи на ідентифікатор об’єкта. Наприклад, можна визначити точку зору клієнта за допомогою атрибутів імені, віку та адреси. Більшість з них можуть змінюватися протягом життя клієнта в системі, але це все той же клієнт з однаковою історією замовлень, тому його ідентифікатор повинен залишатися незмінним (рис. 3.10). Якби система створювала нового клієнта кожен раз, коли змінювалася домашня адреса, це дуже швидко призвело б до плутанини.

Клієнт визначається не його атрибутами, а скоріше його ідентичністю (ідентифікатором), тому його слід моделювати як сутність. Таким чином, поки клієнт існує в системі, його особистість залишається послідовною незалежно від того, скільки разів змінювався його стан за цей час.

Вибір правильного підходу до визначення ідентифікатора сутності дуже важливий, і робити це потрібно обережно. Результатом зазвичай є  ідентифікатор. Це означає, що ідентифікатор ідентифікує ідентичність та унікальність сутності. Іноді унікальний ідентифікатор може бути згенерований, а іноді його отримують шляхом застосування функції до певного набору атрибутів сутності. У другому випадку необхідно переконатися, що жоден із зазначених атрибутів не зміниться з часом. Може виявитися, що Це непросте завдання, оскільки важко передбачити, які атрибути, ймовірно, зміняться в майбутньому, навіть якщо вони здаються фіксованими в даний момент. Тому в цілому в якості ідентифікатора краще використовувати згенеровані унікальні ідентифікатори.

Потрібно також сказати, що поняття ідентифікатора в DDD – це не те ж саме, що тотожність або рівність, які використовуються в багатьох мовах програмування. На Java, наприклад, стандартне рівність об’єктів нічим не відрізняється від рівності екземплярів. Якщо ви явно не визначаєте свій власний  метод equals(), два екземпляри об’єкта, який представляє одного і того ж клієнта, не будуть рівними. Крім того, ідентифікатор не залежить від конкретного представлення сутності. Один і та сама сутність може бути представлена екземпляром об’єкта, документом JSON або двійковими даними.

Локальна, глобальна та зовнішня унікальність

Ідентифікатор об’єкта важливий, але він може бути унікальним на різних рівнях. Візьмемо, наприклад, сутність “клієнт”. Система могла використовувати унікальний ідентифікатор не тільки всередині неї, але і зовні. Такий ідентифікатор називається зовні унікальним. Прикладом можуть служити посвідчення особи або номери, які використовуються в багатьох країнах для ідентифікації громадян. У Сполучених Штатах це номер соціального страхування. Однак Використання ідентифікатора, визначеного поза системою, може мати певні недоліки, які, як ви побачите в наступних розділах, можуть становити загрозу безпеці.

Мабуть, більш поширеними є ідентифікатори, унікальність яких обмежена рамками системи або поточною моделлю. Їх  можна назвати глобально унікальними. Як приклад можна привести унікальний ID, який генерується системою при створенні нового клієнта (рис. 3.11). Тут можуть виникнути цікаві технічні нюанси, на яких варто зупинитися особливо. Якщо ви маєте справу з розподіленою системою і ваші ідентифікатори повинні бути не тільки унікальними,  Але і послідовна, з технічної точки зору, їх генерація може вимагати значних зусиль.

Іноді одні сутності знаходяться всередині інших. Оскільки такими інкапсульованими сутностями керує їх власник, їхні ідентифікатори можуть бути унікальними лише в межах цієї сутності, і цього, як правило, достатньо. Такі ідентифікатори називаються локальними ідентифікаторами на рівні суб’єкта господарювання (рис. 3.12). Повернемося до нашого прикладу і уявимо, що система управляє покупцями в роздрібних магазинах і кожен покупець належить тільки до одного магазину. У цьому випадку Досить зробити ідентифікатор унікальним на рівні магазину, до якого належить клієнт. Моделювання локальної унікальності може спростити функцію генерації ідентифікаторів, а також дозволяє явно перекласти всю відповідальність за управління даними клієнта на сутність, в якій вони інкапсульовані.

Суб’єкти господарювання повинні бути вузькоспеціалізованими

Моделюючи сутність, намагайтеся додавати тільки ті атрибути і поведінку, які важливі для її визначення або допомагають її ідентифікувати. Все інше необхідно перемістити з сутності в інші об’єкти моделі, які потім можна зробити її частиною. Це можуть бути як інші сутності, так і об’єкти, про які ми поговоримо в наступному розділі.

Суб’єкти господарювання займаються координацією операцій, які можуть стосуватися не тільки їх самих, але і їх об’єктів (рис. 3.13). Це важливо, тому що ми можемо мати інваріанти, пов’язані з конкретною операцією. У той же час суб’єкт господарювання несе відповідальність за управління своїм внутрішнім станом та інкапсуляцію своєї поведінки, тому він також повинен володіти операціями для роботи з його вмістом. Переміщення операцій за межі сутності зробило б його слабким (анемічним).

Під час посадки на борт повітряного судна кожен пасажир повинен пред’явити посадковий талон, щоб підтвердити, що він сідає на правильний борт повітряного судна. Це полегшує відстеження зниклих пасажирів перед вильотом. Якби пасажирам дозволили вільно ходити від літака до літака, працівникам аеропорту довелося б перевіряти посадкові талони після того, як усі сядуть на свої місця. Це займе набагато більше часу і може викликати плутанину, якщо пасажири сядуть не в той літак. З огляду на це, контроль і координація пасажирів під час посадки виглядає цілком логічно. Те ж саме стосується і моделі програмного забезпечення, яка описує цей процес.

Якщо ви моделюєте літак як сутність зі списком пасажирів на борту, то інші частини системи не повинні вільно додавати людей до цього списку, інакше буде занадто легко обійти інваріанти.

Пасажир повинен бути доданий методом  board(BoardingPass)  від суб’єкта господарювання «літак». Таким чином, суб’єкт господарювання контролюватиме посадку пасажирів та підтримуватиме правильний стан. Цей спосіб дозволяє здійснити посадку тільки в тому випадку, якщо посадковий талон відповідає поточному рейсу.

Сутності є основним механізмом представлення понять в моделі предметної області, але не всі аспекти моделі визначаються їх ідентифікаторами. Для визначення деяких понять використовуються їх значення. Для моделювання таких понять використовуються ціннісні об’єкти.

Ціннісні об’єкти

Як відомо з попереднього розділу, сутність часто складається з інших об’єктів моделі. Атрибути та поведінка можуть бути вилучені з самої сутності та розміщені в окремих об’єктах. Це можуть бути інші сутності, але в багатьох випадках для цього використовуються ціннісні об’єкти.

Ключові характеристики таких об’єктів перераховані нижче:

  • Визначаються не ідентифікатором, а своїм значенням;

  • Незмінні;

  • Повинні складати цілісну концепцію;

  • Можуть посилатися на сутності;

  • Явно визначають та забезпечують дотримання важливих обмежень;

  • Можуть використовуватися як атрибути в сутності та інших об’єктах-значеннях;

  • Можуть мати короткий час життя.

Як ви побачите в наступних розділах, багато в чому саме завдяки цим властивостям ціннісні об’єкти відіграють важливу роль у написанні безпечного коду на рівні проектування.

Визначається їх величина

Об’єкт цінності визначається його значенням, а не його ідентифікатором, тому два об’єкти одного типу вважаються рівними, якщо їх значення однакові. Нас цікавить тільки  те, що вони собою являють, але не те, що саме вони собою являють. Об’єкти цінності не мають ідентифікаторів. Це повна протилежність тому, як ми визначаємо сутності.

Уявіть, що ваша доменна модель має поняття грошей. Ви можете змоделювати його як ціннісний об’єкт, так як ви не розрізняєте різні монети і купюри. Будь-які дві п’ятидоларові купюри мають однакову вартість. Тут має значення конфесія, а не її фізичне представництво.

ПРИМІТКА. Те, як ви описуєте поняття — як об’єкт цінності без ідентифікатора або сутність з унікальним ідентифікатором — залежить від контексту, з яким ви маєте справу.

Якщо ви моделюєте такий домен, як центральний банк, то гроші, ймовірно, варто моделювати як сутності. Справа в тому, що з точки зору центрального банку кожна п’ятидоларова купюра унікальна, адже вона не тільки друкує їх, а й стежить за їх оборотами і в кінцевому підсумку знищує. Кожна купюра має унікальний серійний номер, який ідентифікує її і дозволяє відрізнити від будь-якої іншої. Використовується до моменту вилучення з обігу, наприклад, для заміни банкнотою нового виду з новим ідентифікатором. З точки зору центрального банку, гроші унікальні і мають життєвий цикл.

Непорушні

Оскільки об’єкти такого роду визначаються їх цінностями, необхідно подбати про те, щоб цінності не змінювалися. В іншому випадку це будуть інші об’єкти. З цієї причини ціннісні об’єкти повинні бути незмінними. Якби їх можна було модифікувати, це могло б порушити інваріанти інших об’єктів, всередині яких вони розташовані. Незмінність також дозволяє передавати об’єкти як аргументи і дозволяє проводити різні технічні оптимізації, такі як повторне використання об’єктів в обмежених пам’яттю середовищах і полегшення роботи з ними в багатопотокових системах.

Цілісна концепція

Об’єкт значення може складатися з одного або декількох атрибутів, або інших подібних об’єктів. Він також може посилатися на сутності, але не може їх містити. Причиною цього є те, що вартість сутності може змінюватися. Якщо об’єкт value не посилався на сутність, а містив її, то будь-яка зміна в ньому змінювало б сам об’єкт. А це порушило б його незмінність.

При моделюванні ціннісного об’єкта і визначенні того, що він повинен містити, важливо переконатися, що він являє собою цілісну концепцію. Іншими словами, це повинен бути єдиний сенс. Тобто об’єкт value повинен бути не тільки зручним контейнером для атрибутів, зв’язків та інших об’єктів, але і формувати чітко визначене поняття в моделі предметної області (рис. 3.14). Це стосується навіть одного атрибута. Коли ваш об’єкт-цінність моделюється як цілісна концепція, його сенс передається разом з ним, і при цьому він здатний зберігати свої обмеження.

3.14 можна побачити два різних підходи до моделювання клієнта та його атрибутів. Ліворуч всі атрибути згруповані разом в об’єкт моделі під назвою CustomerInfo. Праворуч атрибути моделюються для формування чітко визначених понять: вулиця, поштовий індекс та місто групуються в об’єкт значення з іменем Адреса. Номер телефону та адреса електронної пошти розміщуються в  об’єкті значення ContactInfo . А вік став окремим об’єктом.

Потрібно розуміти, що об’єкт значення – це не просто структура даних, яка зберігає значення. Він також може інкапсулювати логіку (іноді нетривіальну), пов’язану з концепцією, яку він представляє. Наприклад, об’єкт значень, що представляє точку координат GPS, може мати метод, який обчислює відстань між собою та іншою точкою за допомогою складних обчислень.

Визначення та застосування важливих обмежень

Уявімо, що у вас є  об’єкт значення Age з  одним цілим числом всередині (рис. 3.15). На Java, наприклад, ціле число за замовчуванням знаходиться в діапазоні від -231 до 231 – 1. Навряд чи такий діапазон можна назвати типовим для людського віку. Тому, щоб уточнити визначення віку, його слід змоделювати як ціннісний об’єкт з відповідними обмеженнями або інваріантами,  Як показано на малюнку.

В ході моделювання можна прийти до висновку, що вік людини повинен бути від 0 до 150 років. Можливо, ваша предметна область не дозволяє дітям, тому мінімальний вік може становити 18 років. Який би діапазон ви не вибрали, він буде набагато суворіше, ніж той, який використовується в Java для цілих чисел.

Варто також зазначити, що типи інваріантів, які ми тут обговорюємо, відрізняються від так званих перевірок валідації. Зазвичай вони проводяться, коли робиться заява про те, що об’єкт домену підходить для певної операції і над ним можна виконати певну дію. Прикладом може бути перевірка готовності замовлення до передачі в систему доставки. Для цього, можливо, доведеться переконатися, що  що замовлення оплачено і містить необхідну адресу. Такі перевірки часто охоплюють кілька об’єктів домену і, як правило, виконуються на якомога пізнішій стадії.

Щебінь

Коли ви маєте справу з об’єктом моделі з життєвим циклом, таким як сутність, вам потрібно переконатися, що його стан залишається правильним протягом усього терміну служби. Для цього вам, можливо, доведеться реалізувати досить багато логіки та використовувати код для роботи з механізмами блокування для підтримки паралельних операцій та запису змін до постійного сховища. Незалежно від  Незалежно від того, збережена сутність чи ні, можна сказати, що зміна стану відбувається в рамках транзакції.

Управління транзакціями зазвичай можливо при роботі з одним суб’єктом. Але насправді ваша модель домену, ймовірно, не така проста, і існує багато зв’язків між її різними сутностями та об’єктами значення. Це означає, що узгодженість, яку потрібно підтримувати, охоплює кілька об’єктів домену. У такій ситуації швидко виникає питання: як управляти транзакціями, в яких беруть участь кілька елементів моделі? Ось для чого призначені одиниці.

Агрегат – це  концептуальна межа, яка може бути використана для групування окремих частин моделі. Це робиться для того, щоб при зміні стану агрегат можна було розглядати як єдине ціле, це межа, в межах якої повинні здійснюватися угоди. Межа, визначена сукупністю, не вибирається довільно або технічно. Вона ретельно формується на основі глибокого розуміння моделі.

При моделюванні агрегату необхідно дотримуватися строгих правил, щоб він справно працював і виконував покладене на нього завдання.

Нижче наведені правила, запропоновані Еріком Евансом.

  • У кожного агрегату є межа і корінь.

  • Роль кореня грає одна конкретна сутність, розміщена всередині агрегату.

  • Корінь є єдиним членом агрегату, на який можуть посилатися об’єкти поза кордону.

Тому:

  • корінь має глобальний ідентифікатор;

  • корінь керує доступом до об’єктів усередині кордону;

  • всі сутності, крім кореня, мають локальні ідентифікатори, які можуть бути невідомі поза агрегату;

  • корінь може передавати іншим об’єктам посилання на внутрішні сутності, але ці посилання можна використовувати лише тимчасово, та його не можна утримувати;

  • корінь може передавати іншим об’єктам посилання на об’єкти-значення.

  • Інваріанти між членами агрегату завжди дотримуються в межах кожної транзакції.

  • Інваріанти, що охоплюють кілька агрегатів, не дають гарантії узгодженості в будь-який момент, але зрештою вони можуть стати узгодженими.

  • Об’єкти всередині агрегату можуть містити посилання на інші агрегати.

Це досить широкий набір правил, і вам, ймовірно, варто пройти його ще раз і подумати про їх значення і наслідки, які кожен з них буде мати не тільки для архітектури вашої моделі, але і для коду. Однак тут є кілька моментів, які ми хотіли б прояснити.

Сукупність – це концептуальна межа, і вона містить сутність, яка є її коренем. У загальному випадку на етапі реалізації коренева сутність і сама сукупність – це один і той же об’єкт. Можливо, вам буде легше говорити про них, якщо ви вважаєте їх ідентичними.

 Корінь агрегату – це єдина частина агрегату, яка видима за його  межами. Root контролює доступ до всього всередині агрегату. Це робить його ідеальним місцем для розміщення всіх інваріантів, що охоплюють різні об’єкти, в межах. Його неможливо обійти, за умови дотримання правил моделювання агрегатів. Це також означає, що root є єдиним елементом, доступ до якого можна отримати через репозиторій (див. бічну панель). Це ще один спосіб управління доступом до агрегату, який гарантує, що сутності, які знаходяться всередині нього, не можуть бути безпосередньо змінені зовнішніми об’єктами.

СХОВИЩЕ

Ми не будемо вдаватися в подробиці про репозиторії, але ви можете думати про них як про технологічно незалежні сховища для агрегатних коренів. Коріння можна зберігати у сховищі та виводити їх із системи пізніше. Репозиторії також дозволяють видаляти раніше збережені коріння, якщо ваша модель це підтримує.

Агрегації, разом з їх межами та послідовною державною підтримкою, можуть відігравати важливу роль у забезпеченні безпеки вашого коду. Давайте розглянемо на прикладі, як змоделювати простий агрегат.

Демонстраційна модель складається з компанії та її співробітників. Ми зробимо компанію суб’єктом господарювання, тому що вона повинна бути глобально ідентифікованою. Він має назву, але це просто значення, тому давайте думати про нього як про ціннісний об’єкт. У компанії працюють співробітники. Кожен з них чітко має ідентифікатор, тому він також буде змодельований як сутність. Співробітник завжди належить компанії, тому він буде її дитиною. У кожного працівника є певна роль, але вона також є цінністю, тому буде представлена ціннісним об’єктом. Остаточна модель показана на рис. 3.16.

Обговоривши характер працівника з профільними експертами, ви зрозуміли, що його не потрібно ідентифікувати за межами компанії. Робочий об’єкт може мати локальний ідентифікатор. Ви також помітили, що деякі ролі можуть бути призначені лише окремим працівникам. Наприклад, компанія може мати тільки одного технічного директора. Те ж саме стосується і багатьох інших ролей. Щоб зберегти ці інваріанти, суб’єкт господарювання компанії повинен керувати процесом розподілу ролей серед співробітників. З цього випливає, що компанія і всі її дочірні підприємства повинні бути змодельовані у вигляді сукупності. Коренем підрозділу буде сама компанія. Результат показаний на рис. 3.17.

Це означає, що на компанію можна посилатися зовні, оскільки вона глобально ідентифікована, однак доступ до працівника може бути доступний лише через корінь сукупності, тобто через саму компанію. Те ж саме стосується і призначення ролей працівникам. Робиться це за допомогою методу, що належить компанії. Оскільки всі операції з агрегатом контролюються його коренем, дотримання інваріантів, пов’язаних з робочими, стає досить простим завданням.

У цьому розділі ви дізналися основи фундаментальних будівельних блоків, які використовуються для створення моделей доменів в DDD. Ми розглянули досить багато матеріалу, і може знадобитися деякий час, щоб належним чином засвоїти всю цю інформацію. Далі ми поговоримо про обмежені контексти, ще одну важливу концепцію зі світу DDD, яку ви повинні зрозуміти, перш ніж перейти до решти розділів цієї книги.

Обмежені контексти

Шаблон проектування Bounded Context – ще одна цікава концепція, яка визначає сферу застосування моделі предметної області. Він грає важливу роль не тільки в DDD, але і в області безпеки. Використання обмежених контекстів як основи для аналізу допомагає краще зрозуміти складні атаки. Щоб переконатися в цьому, потрібно правильно зрозуміти це поняття, тому спочатку зануримося в семантику окремо взятої мови.

Семантика однієї мови

У DDD єдиною мовою вважається розмовляє кожен і завжди і який забезпечує ясність і взаєморозуміння (рис. 3.18).

Оскільки ми говоримо «все», «завжди» і «скрізь», легко подумати, що мова йде про єдину мову з термінами, операціями і поняттями, які охоплюють всю сферу бізнесу, але це абсолютно не так. Той, хто пробував реалізувати таку мову, знає, що ця ідея приречена на провал через свою надмірну складність. І причина цього криється в семантиці.

Термін або поняття може мати однакове ім’я в різних частинах предметної області, але його значення можуть відрізнятися. Взяти, наприклад, слово «пакет». Якщо ви запитаєте когось у відділі доставки про його значення, вони скажуть вам, що це упаковка, але якщо ви задасте це ж питання IT-фахівцю, вони пояснять вам, що це спосіб логічного групування файлів у кодовій базі. Термін «пакет» використовується то тут, то там, але з різною семантикою. Спроба висловити це на одній мові навряд чи буде успішною, так як для цього буде потрібно створення нового терміна, що включає в себе обидва значення. Очевидним рішенням тут було б використання двох паралельних мов замість однієї єдиної мови з неточною семантикою. Тепер давайте подивимося, як одна мова має відношення до моделей і обмежених контекстів.

Зв’язок між мовою, моделлю та обмеженим контекстом

Взаємозв’язок між мовою, моделлю і обмеженим контекстом стає очевидною, якщо розглядати її з точки зору семантики. Модель  – це абстракція предметної області, в якій знаходяться поняття, відносини і терміни однієї мови. Це тісно пов’язує мову і модель один з одним – і не тільки за рахунок термінів і відносин, але і на рівні семантики: приналежність поняття до моделі повинно мати той же сенс, що і в мові, і навпаки.

Модель залишається послідовною, якщо семантика її термінів, операцій і понять не змінюється. Однак при будь-якій зміні семантики модель порушується і межа контексту стає очевидною. Це дуже важливо розуміти, адже саме тут значення терміна може змінитися тільки тому, що він перетнув кордон. Це означає, що все всередині контексту відповідає семантиці моделі, а поза одними і тими ж термінами може мати різну семантику. Звучить цілком логічно, але трохи абстрактно.

Давайте розглянемо приклад, в якому ми описуємо єдину мову, створюємо модель і використовуємо її для визначення семантичної межі контексту.

Визначення обмеженого контексту

Визначення обмеженого контексту може починатися з аналізу однієї мови. Візьмемо, наприклад, наступний діалог між розробником і фахівцем з доставки.

Розробник: Чим характеризується замовлення?

Спеціаліст: Замовлення містить товари, які продаються і не продаються.

Розробник: Не  зовсім зрозуміло. Що ви маєте на увазі під непроданими продуктами?

Спеціаліст: Це  продукти, які додаються до проданого товару, коли упаковка відправляється до місця призначення.

Розробник: О, я бачу. Ці продукти без ціни?

Спеціаліст: Ні, ні! Всі товари мають ціну, а ось ті, що не продаються, мають нуль, тому додаються безкоштовно.

Розробник: Хм , добре. Звучить логічно.

На даному етапі ще багато плутанини, але ми вже можемо виділити важливі терміни і висловити їх у вигляді чорнового варіанту моделі предметної області (рис. 3.19).

Одним з ключових принципів спільної мови є уникнення невизначеностей, так як вони створюють багато плутанини і непорозумінь. Це можна побачити на рис. 3.19, де модель має багато неоднозначних і повторюваних понять. Давайте повернемося до попереднього діалогу і подивимося, як еволюціонує наша мова і модель.

Розробник: Мене трохи бентежить термінологія. Може бути, ми домовимося про використання якихось загальних термінів?

Спеціаліст: Звичайно. Ви вже маєте на увазі щось конкретне?

Розробник: Мабуть, у нас є тільки продукти. Може бути, ми перестанемо використовувати такі слова, як «об’єкти», «речі», «продано» і «непродаваний»?

Спеціаліст: Гаразд, це звучить логічно. Відтепер ми будемо називати всі ці продукти.

Розробник: “Включено” і ”  включено” – це одне і те ж, чи не так?” Фахівець: Так, давайте використовувати тільки  “прикріплений” тоді.

Забудовник: А як щодо ціни і вартості?

Спеціаліст: Це одне й те саме. Зупинимося на ціні.

Розробник: Чому ми повинні піклуватися про те, безкоштовний продукт чи ні?

Спеціаліст: Ви маєте рацію. Давайте більше не будемо використовувати слово «вільний».

В результаті процесу дистиляції ми отримали набагато більш лаконічну мову і оптимізовану модель предметної області (рис. 3.20).

Але іноді дистиляція дозволяє виявити відсутні терміни, як показано нижче.

Розробник: чи може замовлення містити один або кілька товарів?

Спеціаліст: Саме так. А ось для замовлення без продуктів пакет навряд чи знадобиться.

Розробник: Пакет?

Спеціаліст: Ах, вибачте. Посилкою називаємо упаковку, в якій відправляється замовлення.

Розробник: Гаразд, це звучить логічно. Але як ми знаємо, скільки продуктів потрібно відправити в упаковці?

Спеціаліст: Кількість одиниць кожного товару вказується в замовленні.

Розробник: Так, я бачу. Давайте додамо «кількість» і «пакет» до нашої уніфікованої мови і моделі.

Після цієї доопрацювання (рис. 3.21) розробник і фахівець цілком впевнені в тому, що у них є спільне бачення і розуміння замовлення.

Але наскільки глибоко модель проникає в організацію? Коли ця модель перестала відповідати бізнесу? Відповіді на ці питання є ключовими для визначення межі контексту. Забудовник починає розпитувати оточуючих, і здається, що у відділі доставки є взаєморозуміння. Але, звернувшись до фахівця з фінансового відділу, забудовник раптом виявляє порушення моделі.

Розробник: Будь ласка, подивіться на нашу модель замовлення.

Фахівець з фінансів: Звичайно. Модель виглядає логічно, але ви, здається, упустили багато важливих понять.

Розробник: Дійсно? Поясніть, будь ласка.

Фінансовий спеціаліст: Інформації про платіж і терміни виконання немає. Я також не бачу зарезервованої суми.

Розробник: Так. Схоже, ми використовуємо різні визначення замовлень. Дякую за ваш час.

Як тільки семантика моделі порушується, межа контексту стає очевидною. Виявивши, де саме виникають протиріччя, забудовник швидко розуміє, що в сферах фінансів і доставки замовлення означає різні речі. Це підкаже вам, де проходить межа контексту. Ми можемо проілюструвати це у вигляді двох окремих контекстів, кожен з яких представляє поняття впорядкування з різним змістом (рис. 3.22).

Але що, якщо нам потрібно взаємодіяти і передавати накази між контекстами? Чи існують інші схожі поняття з різною семантикою? Це підводить нас до наступної теми, яка полягає у взаємодії між контекстами.

Сумісність між контекстами

Межа контексту представляє інтерес з точки зору безпеки. Давайте подумаємо, як відбувається взаємодія між контекстами. Коли дані перетинають межу, вони автоматично набувають семантики однієї мови та моделі іншого контексту. Звідси випливає, що бездіяльність в цьому процесі створює ризик вразливостей. І хоча це може здатися очевидним, проблеми подібного роду дивно поширені.

За іронією долі, основною причиною цього може бути спроба слідувати принципу DRY (Не повторюйся). Ендрю Хант і Девід Томас визначають цей принцип наступним чином:

Кожна частина знань повинна мати єдине, послідовне і авторитетне уявлення всередині системи.

Хант А., Томас Д. Прагматичний програміст (Аддісон-Уеслі, 2003)

Багато хто трактує його як уникнення синтаксичного дублювання, яке виникає, наприклад, при ручному копіюванні коду, але цей принцип застосовується і до семантики. І це повертає нас до спільної мови.

Одна мова вимагає, щоб семантика моделі предметної області була однозначною у всьому контексті. Але якщо керуватися синтаксичною інтерпретацією принципу DRY, метод обміну даними між контекстами раптом перетворюється з семантичного питання в технічний. І це величезна проблема, тому що якщо застосовувати загальні моделі для зменшення дублювання коду, а деякі поняття в них означають різні речі, це робить з можливих будь-які, самі божевільні проблеми, включаючи дірки в безпеці. Щоб проілюструвати це, давайте повернемося до прикладу контекстів доставки та фінансування, але цього разу ми спробуємо зменшити синтаксичне дублювання за допомогою загальної моделі.

Використання однієї і тієї ж моделі в двох контекстах

У сферах доставки та фінансів використовуються такі поняття, як замовлення, продукт і ціна. Аргументи на користь наявності спільної моделі дійсно переконливі, оскільки вона зменшує дублювання. Але для цього потрібно запозичити ще кілька понять з фінансової сфери (рис. 3.23).

На перший погляд, використання уніфікованої моделі виявилося великою удачею. Єдиним видимим недоліком є те, що модель вийшла насиченою, з декількома додатковими концепціями. Але давайте подивимося, що станеться, коли з’явиться нова бізнес-вимога в контексті доставки.

Спеціаліст: Для спрощення митних декларацій для міжнародних перевезень нам потрібно вказати фактичну вартість посилки.

Розробник: Добре. Але що ви робите з включеними продуктами в цьому випадку?

Спеціаліст: Раніше ми робили продукт безкоштовним, штучно обнуляючи його ціну, але більше цього робити не можна.

Розробник: Саме так. Може, ми просто приберемо фіктивну ціну?

Спеціаліст: Так,  вартість пакету дорівнює сумі всіх цін, тому він повинен працювати.

Розробник: А потім відніміть ціни на додані елементи із загальної суми, чи не так?

Спеціаліст: Ні,  у рахунку, виставленому фінансовим відділом, вказана зарезервована сума, тому нам не потрібно нічого відраховувати.

Розробник: Звучить логічно. Тоді я просто приберу фіктивні ціни.

Для внесення змін не потрібно багато зусиль, і спочатку все добре працює, але через деякий час у фінансовому відділі починають спостерігатися дивні речі. Чомусь  іноді порушується інваріант «зарезервована  сума сума всіх цін». Ця проблема може здатися несуттєвою, оскільки це відбувається лише тоді, коли додаються безкоштовні продукти. Але в результаті за його фактом розпочинається повномасштабне розслідування. Порушення інваріанта рівнозначно Фальсифікація наказу, а це серйозна діра в безпеці!

Розслідування не виявило жодних вразливостей, але те, що проста зміна може мати такі наслідки, досить цікавий. Подальший аналіз показав, що справжньою першопричиною було використання єдиної моделі в двох концептуальних уявленнях порядку. Інваріант  «зарезервована  сума сума всіх цін» має сенс тільки у фінансовому контексті. Але так як існує загальна модель, відділ доставки змушений дотримуватися цей інваріант, незважаючи на те, що У цьому контексті це безглуздо. Це очевидна проблема, оскільки вона заважає контекстам бути незалежними та володіти власними моделями. Але якщо ми не застосовуємо загальну модель, звідки ми знаємо, які поняття вимагають особливої уваги при взаємодії між різними контекстами? Рішенням є створення контекстної карти.

Створення контекстної карти

Контекстна карта –  це концептуальне уявлення про те, як взаємодіють різні контексти. Це може бути схема, текстовий опис або просто взаєморозуміння між командами. У будь-якому випадку його ключова особливість полягає в тому, що він допомагає виявити поняття, які перетинають смислові межі.

Неправильно складена карта часто стає причиною непорозумінь, які можуть привести до проблем з безпекою. Таким чином, визначення меж контексту дуже важливо, але це легше сказати, ніж зробити. Якщо ви не знаєте, з чого почати, закон Конвея – відмінне рішення. У 1968 році Мел Конвей опублікував статтю під назвою « Як комітети винаходять?, де він висунув наступну тезу.

Будь-яка організація, яка розробляє систему (в широкому сенсі), створить проект, структура якого є копією структури відносин організації.

Конвей М. Як винаходять комітети? (Datamation, 1968)

Звідси випливає, що комунікаційні структури, які існують в організації, часто відображаються в архітектурі системи. Здається, це стосується способу визначення обмежених контекстів. Багато команд, як правило, організовують свою роботу навколо підсистем, і обмежені контексти часто слідують тій же логіці. Тому процес поділу працівників на команди є гарною можливістю визначити обмежені контексти для вашої карти.

Щоб проілюструвати, як може виглядати графічне представлення контекстної карти, повернімося до відділів доставки та фінансів. Для початку корисно буде намалювати просту загальну схему взаємодій всередині системи при обробці замовлення (рис. 3.24).

Ось як працюють команди з фінансів і доставки.

  1. Фінансовий відділ отримує новий наказ.

  2. Загальна сума замовлення резервується на рахунок, вказаний в платіжній інформації.

  3. Фінансовий відділ передає замовлення у відділ доставки для обробки.

  4. Відділ доставки обробляє і відправляє замовлення.

  5. Відділ доставки повідомляє фінансовий відділ про новий статус замовлення.

  6. Фінансовий відділ завершує касову операцію.

Цю блок-схему можна легко перетворити в контекстну карту, з якої стає зрозуміло, що контекст доставки вторинний по відношенню до контексту фінансів (рис. 3.25). Це може здатися очевидним, але розуміння того, що фінансове замовлення потрібно перетворити в замовлення на доставку, має першорядне значення. Таке ставлення чітко вказує на необхідність чітких зв’язків і на те, що команди повинні працювати разом, щоб досягти успіху.

Ви вже повинні мати концептуальне розуміння того, чому обмежені контексти важливі і як створюються їхні карти, але нам ще належить пояснити, як вони пов’язані з безпекою. У наступних розділах ви побачите, як обмежені контексти можуть допомогти вам проаналізувати ваш код на наявність вразливостей. Наприклад, в главі 9 ми розглянемо обробку несправностей, а в главах 12 і 13 поговоримо про роботу зі старим кодом.

У наступному розділі ви дізнаєтеся про концепції програмування, які можуть підвищити безпеку, використовуючи ідеї з цієї глави та інших областей. Ви зможете застосовувати їх у своїй повсякденній роботі і навчитеся виявляти вразливості в існуючій кодовій базі.

Резюме

  • Створення доменних моделей — гарна можливість набути глибоких знань про предметну область.

  • Доменна модель має бути строгим та недвозначним уявленням предметної області та охоплювати лише найважливіші її аспекти.

  • При створенні доменної моделі ми робимо вибір між безліччю різних її варіантів.

  • Доменна модель формує мову для обговорення системи.

  • Сутності, об’єкти-значення та агрегати – головні складові елементи вашої доменної моделі.

  • Сутність містить ідентифікатор, який залишається незмінним протягом її життєвого циклу, і може складатися з інших сутностей або об’єктів значень.

  • Унікальність сутності завжди обмежена якоюсь областю, яка залежить від моделі.

  • Об’єкт-значення не має ідентифікатора, він визначається своїм значенням.

  • Об’єкт-значення завжди повинен залишатися незмінним та формувати цілісну концепцію.

  • Агрегат – це концептуальна межа, яка поєднує інші об’єкти моделі та відповідає за дотримання інваріантів між цими об’єктами.

  • У агрегату завжди є корінь, який у коді зазвичай збігається із самим агрегатом.

  • Корінь агрегату має глобальний ідентифікатор, оскільки це єдина частина агрегату, яку можуть посилатися інші елементи моделі.

  • Єдина мова використовується всіма членами команди, включаючи фахівців у предметній галузі. Це забезпечує порозуміння.

  • Доменна модель обмежена семантикою єдиної мови.

  • Обмеженим називають контекст, у якого дотримується семантика моделі. Будь-яка зміна семантики призводить до порушення моделі, що дозволяє визначити межу контексту.

  • Визначення межі контексту можна розпочати із застосування закону Конвею.

  • Дані, що перетинають семантичну межу, становлять особливий інтерес з погляду безпеки, оскільки при перетині значення концепції може змінитися.

Ми використовували матеріали з книги “Безпека by design”, які  написали Дэн Берг Джонсон, Дэниел Деоган, Дэниел Савано.

Інші статті по темі
ОсвітаСамонавчання
Читати далі
Безпека by design. Частина 1. (Роль проектування у безпеці)
Проектування відіграє надзвичайно важливу роль у гарантуванні безпеки в різних сферах, від технологій до інфраструктури та бізнесу. Цей процес є фундаментальною складовою для створення рішень, які ефективно запобігають загрозам, забезпечують конфіденційність та зберігають цінності. Розглянемо ключові аспекти ролі проектування у забезпеченні безпеки.
1258
ОсвітаСамонавчання
Читати далі
Безпека by design. Частина 2. (Антракт: анти-“Гамлет”)
У цій статті описується роль глибокого моделювання у забезпеченні безпеки інформаційних систем та бізнес-цілісності. Розглядаються ризики поверхового моделювання, які можуть призвести до недостатнього рівня захисту та дефективної безпеки.
897
ОсвітаСамонавчання
Читати далі
Безпека by design. Частина 4. (Концепції програмування, що сприяють безпеки)
Застосування цих концепцій у програмуванні сприяє підвищенню рівня інформаційної безпеки. Вони допомагають уникнути загроз та вразливостей, забезпечуючи захист даних та надійність програмних продуктів.
997
ОсвітаСамонавчання
Читати далі
Безпека by design. Частина 5. (Доменні притиви)
У цій частині. Як доменні примітиви допомагають писати безпечний код. Боротьба з витоком даних за допомогою об'єктів одноразового читання. Поліпшення сутностей з допомогою доменних примітивів. Ідеї, запозичені із аналізу помічених даних.
932
ОсвітаСамонавчання
Читати далі
Безпека by design. Частина 8. (Роль процесу доставки коду у безпеці)
У цій частині. Модульні випробування, спрямовані на безпеку. Перемикачі функціональності з погляду безпеки. Написання автоматизованих тестів безпеки. Чому важливими є тести доступності. Як неправильна конфігурація призводить до проблем безпеки.
1011
Знайшли помилку?
Якщо ви знайшли помилку, зробіть скріншот і надішліть його боту.