Чи йдуть непорушні об'єкти та DDD разом?


18

Розглянемо систему, яка використовує DDD (також: будь-яка система, яка використовує ORM). Суть будь-якої системи реально, майже в кожному випадку використання, полягає в маніпулюванні цими об’єктами домену. Інакше немає реального ефекту чи мети.

Змінення незмінного об'єкта призведе до того, що після збереження об'єкта він генерує нову запис, що створює масовий розрив у джерелі даних (якщо ви не видаляєте попередні записи після модифікацій).

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


Відповіді:


16

Обчислення з використанням незмінних об'єктів (як у функціональному програмуванні) не обов'язково передбачає збереження кожного створеного об'єкта!


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

1
я думав, що незмінні об'єкти будуть корисні для проміжних обчислень (паралельними нитками)
Стівен А. Лоу,

11

Чи означає незмінний у домені, що він повинен бути незмінним у базі даних? Наприклад, розглянемо наступне, якщо клієнт завжди має одну адресу:

customer.address = new Address('My Castle', 'Kings street');
customer_repo.save(customer);

тепер працює наступний sql з урахуванням ідентифікатора клієнта 1:

INSERT INTO addresses (customer_id, name, street)
VALUES (1, 'My Castle', 'Kings street');

Тепер у адресу внесено наступні зміни:

customer.address = new Address('Pauper palace', 'Outlands');
customer_repo.save(customer);

і стійкий шар, будучи дуже розумним, виконує наступні sql:

UPDATE addresses SET name='Pauper palance', street='Outlands'
WHERE customer_id = 1;

Таким чином ви уникаєте накладних витрат окремої операції DELETE AND INSERT. Крім того, я думаю, що деякі RDBMS мають INSERT ЗАміну або щось подібне. MySql має ЗАМІНИ .


+1 Я згоден з вами на загальному принципі: я не бачу, чому незмінні об’єкти домену обов'язково повинні означати незмінні рядки БД.
Андрес Ф.

У наведеному вище випадку, якщо нам коли-небудь потрібно змінити атрибут міста адресного класу для даного клієнта, як ми будемо з ним поводитися ?, Далі припускаємо, що клієнт може мати декілька адрес, так що це один із багатьох відносин між клієнтом та адресами
Sudarshan

1
@Sudarshan - це лише спосіб зробити "об'єкт незмінного значення", не дуже непорушний у базі даних. З міркувань продуктивності. Кожну ситуацію потрібно вирішувати спеціально, звичайно. Зараз я віддаю перевагу Sourcing подій для свого домену, але я певним чином захоплююся ним.
andho

@Sudarshan щоб відповісти на ваше запитання конкретно, ви просто запустите запит на оновлення, який оновлює рядок до нового значення. Якщо він один-до-багатьох, то адреси матимуть якийсь ідентифікатор всередині кореневого агрегата клієнта, який буде використовуватися для унікальної ідентифікації його в БД. Тоді цей ідентифікатор і customer_id буде використовуватися для оновлення цього рядка в таблиці "адреси".
andho

@andho "це лише спосіб зробити" об'єкт незмінного значення ", не дійсно незмінний в базі даних". це справді зробило мені подяку
Сударшан

6

У DDD незмінні об'єкти в значній мірі прирівнюються до об'єктів цінності. Ці об'єкти не є сутностями, вони не мають ідентичності. Тому я завжди зберігаю ціннісні об'єкти як стовпчики сутності, в яких вони містяться (з N / Hibernate ви можете використовувати для цього компоненти). У них немає власної таблиці.


4

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

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

Загалом наявність незмінних об'єктів домену (замість просто їх компонентів) здається дещо невідповідністю із наполегливістю.


Зовсім ні. Компоненти дуже корисні, оскільки дозволяють об'єкти домену складатися по-різному від одних і тих же базових даних. Проблеми пов'язані із забезпеченням незмінності. Особисто я б вважав об'єкти домену як змінні (за винятком полів первинного ключа) і тримати його просто.
Gary Rowe

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

Уникайте компонентів, коли одне ціле об'єднання повністю представлено рядком, і жодна з даних не поділяється іншим об'єктом домену.
Гері Роу

4

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

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

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

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

  • У вас немає всюдисущої мови. Мова та поняття в доменній моделі не відповідають тому, що використовують доменні експерти.

Примітка: DDD використовує незмінні об'єкти, де це доречно, їх просто називають об'єктами цінності.

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


Петро, ​​чудова відповідь. Ви можете поглянути на моє запитання тут stackoverflow.com/questions/13783666/… та допоможете мені розібратися у моїй проблемі. Я думаю, що об'єкти незмінної цінності чудово підходять для програмного забезпечення, яке не пов'язане з підприємством. На мою думку, більшість об'єктів корпоративних програм є змінними. Уявіть, що ви маєте незмінний об'єкт глибоко вкладеного значення ... ContactInfo-> PhysicalLocation-> Адреса, і ви хочете оновити поштовий індекс ... створення всього графіка об'єкта здається мені антихристом, а не лише антипатерном. що ти думаєш?
Пепіто Фернандес

3

Якщо ви використовуєте ORM, наприклад Hibernate / NHibernate, ви можете встановити каскадний параметр для автоматичного видалення осиротілих об'єктів. Якщо у людини є об'єкт значення, адреса, коли ви змінюєте адресу, нова буде збережена, а стара видалена, оскільки вона осиротіла.


0

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


-1

Є ще один спосіб використання незмінних об'єктів ...

Замість того, щоб зберігати значення 5.0, 6.0, 7.0, 8.0 і копіювати весь запис кожен раз, ви можете замість цього зберегти щось подібне: 5.0, +1.0, +1.0, +1.0, а потім правильно побудувати залежності для реконструкції послідовності 5.0 , 6,0, 7,0, 8,0. Таким чином, невеликі модифікації займають лише невеликий об'єм пам'яті ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.