Повертаємося до початку.
Архітектура і алгоритми це різні речі.
Яка різниця як воно реалізовано всередині. Тут вже що найменьше 3 оптимізації були описані. І ще можна 100500 оптимізацій придумати, щоб воно взагалі за мілісекунди працювало.
Архітектура DDD це про те, що доменний обєкт Task.UpdateStatus(Done) вміє всередині переводити саб таски в Done. Як він це робить — це вже його проблеми. DDD на це питання не має відповідати. DDD лише відповідає на питання, що всі хто працює з Task — не повині писати зайвого коду для обробки Sub Task на своєму рівні, вся ця логіка інкапсульована в доменному обєкті.
І це все.
Але щоб викликати ChildNode.UpdateStatus всередині Domain Object треба, очевидно, його туди якось завантажити, ні?
Очевидно що ні. Щоб обновити статус вам треба знати лише Id сабтаски, та статус в який ви її переводите. Вся інша інфа зайва в памяті в вашому контексті.
А оце мене, власне, і цікавить. Як, наприклад, зробити такий юзкейс — примусове переведення таски (і всього графу її підтасок) в DONE — в стилі DDD?
Навіщо грузити граф?
Класика, коли ви викликаєте Node.UpdateStatus, це також викликає у всіх ChildNode.UpdateStatus всередині Domain Object.
Розумію що ви натякаєте на якісь Bulk Update, але той балк буде ефективнішим коли в вас тих 500 сабтасок. Але судячі з вашої задачі то біт оптимізація, тож в вас є всі шанси лишити красиву DDD ієрархію.
За допомогою GPT я змогла реалізувати цей проект всього за тиждень!
Це звісно добре, що ви витратили тиждень з GPT, але як і в цій темі
dou.ua/forums/topic/45944
те що ви робили тиждень, можна було написати за 15 хвилин і 15 рядків коду.
При умові використання правильних інструментів, звісно.
github.com/...x2/Sandbox2Application.cs
Проєкт що калькулює ціну пального, може бути корисним для подорожуючих,
створено та задеплоєно поки закіпав чайник.
fraplat.com/jupiter/Sandbox2
За тиждень (5 днів) можна вже написати клон UTube десь на
там десь 450 рядків коду + дизайн,
fraplat.com/jupiter/UTube
Висновок: GPT + сучасні методи розробки (Python, Java і тп) це дуже не ефективні засоби розробки і мене дуже дивує терпіння та наполегливість людей, котрі то все використовують.
Я дуже лінивий, тому GPT не використовую для програмування, віддаючи перевагу правильним інструментам а не генератору токенів на неефективних мовах програмування.
Я бачу проблему в тому, що, якщо в доменному класі Task є сабтаски — то це вдарить по перфомансу (витягувати всю ієрархію), а якщо нема — то робота с сабтасками буде в сервісному шарі, що ламає всю концепцію. Як вийти з цього протиріччя?
Архітектура і алгоритми це різні речі.
Оптимізацію можна зробити в реактивному стилі, наприклад коли в сабтасці статус Done, вона звертається до свого Parent та робить інкремент ++subTasksDone. Коли subTasksDone == countSubTasks статус парента Done.
На все це ніяк не впливає DDD, доменний обєкт інкапсулює свою логіку роботи, його контракти від внутрішніх оптимізацій не змінюються.
Це до мене питання? Перечитайте уважніше мій пост.
Я всього лиш дав референц, що не потрібно це нижче обговорювати. Це як обговорювати асемблер, можна, але навіщо. Тут я лише щоб показувати прийоми програмування, які дійсно скорочують обєм робіт в
Блін, сорян, я забув шо ти в вакуумі і при цьому не думаєш на крок вперед, тому не в курсі що бмпн потрібен для того, щоб його автоматизувати, і тому існують бпмн-двіжки. Це дуже складна думка, да.
Фрактал це і є такий движок. На ньому біля 70% відсотків системи конфігуриться, що називається на льоту.
Погугли нащо це треба, почитай і усвідом, що твоя БД це не вміє принципово. Тому в реальному світі є клас задач, які не вкладаються в raw data + dimensions, що є наріжним каменем твоєї БД.
Що конкретно не може принципово? Ти досі не можеш сформулювати приклад, який принципово недосяжний на «бд з діменшинами».
Є облікові системи на 300+ таблиць які повністью модулюють твої BPMN на Фрактал, розсилки, проходження по статусам, тікети і багато іншого.
ДДД це не про те щоб наляпати DTO класів в найпростішій задачі.
ДДД це про те щоб побудувати N layers, де це справді потрбно.
Тобто обєкт обростає кількома прошарками бізнес логіки.
Доречі, гарний приклад є в ігровій індустрії. В них ігрові персонажі та предмети — це фактично доменні обєкти, з купою своєї внутрішньої логіки. А ті хто цим всім оперує — це сценарій, скрипти, які пишуть гейм дизайнери ігрових рівнів. Це класичний приклад DDD, а не твій копійчаний круд з котом.
Ну тобто приклад який саме тебе цікавить, ти все ще не можеш придумати? Ок.
en.wikipedia.org/...rocess_Model_and_Notation
І що, навіть найпростіший проєкт що перевіряє світло по таймеру,
та розсилає сповіщення вже формально підпадає під твою діаграму
upload.wikimedia.org/...ProcessWithNormalFlow.svg
Timer => Check Status Electricity => If Changed, send telegram message to user group => If failed, retry, try resend messages in case of gateway issues
Подробиці з повним розбором коду проєкту
dou.ua/forums/topic/45479
Гарна риса технічного спеціаліста, приводити приклади, що саме маєш на увазі, що саме хочеш запрограмувати. Наприклад Констянтин зробив як гарний спеціаліст, він свій абзац з запитаннями закінчив прикладом, що хоче побачити Ordering в магазині. І я йому прислав приклад коду, що моделює заповнення корзини з товарами, та замовлення.
github.com/...SupermarketApplication.cs
В тебе ж дуже зручна позиція для дискусії, максимально зашифрувати що ти маєш на увазі, щоб ніхто не додумався і не розібрав твій приклад. Що показує тебе як спеціаліста, що ніби якісь абревіатури вивчив, але зовсім не розуміє де і як, та на яких прикладах це можна застосувати.
З такою позицією не зможу бути корисним в дискусії.
BPMN
Багаторівневе Security, що спадкується, відноситься до нього ? fraplat.com/...nsionsPages/Security.html
StateMachine для проводу документів по статусам, відноситься до нього?
fraplat.com/...nsPages/StateMachine.html
Синхронизація, відноситься до нього?
fraplat.com/...DimensionsPages/Sync.html
Транзакції, відноситься до нього?
fraplat.com/...onsPages/Transaction.html
Дмитро, я дуже люблю практичні приклади по DDD/CMDD і дуже не люблю демагогію, де купу часу витрачають про наслідування між квадратом та прямокутником, setOwner, activeRecord та інший «rocket science» в якому ти нижче з задоволенням приймаєш участь.
Мене цікавлять як замість 50 тис рядків boiler plate, писати
Є код, є приклади, є задеплоєні проєкти. Як ні, то ні, не всім бути реформаторами. Деякі відчайдушно чіпляються за старі технології, навіть якщо вони не дають ніяких переваг.
Бо яка така властивість «пагінація» (чи «сортування») може бути у юзера?
Насправді, в фундаменті є потужна математична модель. Люба колекція з json документами, це фактично колекція ієрархічних обєктів. В ієрархії можуть бути інші вкладені обєкти. А над цими списками може бути застосована така властивість як Pagination. Фактично цей dimension каже, що всі клієнти будуть чититати не всі обєкти скопом, а пейджами.
Приклад, фотоальбом. Є документи (зараз один але може бути більше)
github.com/...hotoAlbum/Photos/Document
{'Photos':['Photo1','Photo2','Photo3']}
А є pagination dimension, який каже що не всі обєкти з масиву Photos ми читаємо, а читаємо порціями по два елемента
github.com/.../Document/0000000000.json
{ "Photos": { "Page": { "Attrs": 2, "IsAlign": false } } }
Перевага такого підходу очевидна. Спочатку ми мали лише анемічну модель, де відображали всі фото на одній сторінці. За допомогою Pagination збагатили логіку і у нас зявився пейджинг. При цьому ми не переписували старий код, навіть якщо його писали без урахування пейджингу.
Покажи, як за допомогою твої діменшнів змоделювати якийсь простий і більшості зрозумілий процес — щось «тривіальне», на кшталт проходження заказу в інтернет-магазині (можливо вже є приклади?)
Це дуже просто, наприклад в нас є документ в колекції Backets
{ "Client": "Bob" "Orders": [] }
В нас є шаблон замовлення, в колеції NewOrder
{ "Name": "Apple M1", "Category": "Notebooks", "Price": 1000, "Quantity": 1 }
Далі ми пишемо в код
CreateNewDocForArray("NewOrder", "Backets", "{'Orders':[$]}").OpenForm();
Відкривається веб форма, після її заповнення, замовлення додається в Backet (корзину)
{ "Client": "Bob" "Orders": [{ "Name": "Apple M1", "Category": "Notebooks", "Price": 1000, "Quantity": 1 }] }
Dimensions на справді дуже багато, більше 50
fraplat.com/...nsionsPages/Document.html
Всі вони є фактично частиною DDD, та допомогають побудувати Rich обєкт.
Коли ви побудували його (фактично наконфігуривши джисони) вам лишається лише описати загальні сценарії роботи з цими доменними обєктами. Підход дуже простий і гнучкий.
Я би сказав, що справжні ідеї DDD розкриває CMDD в Fractal.
Він данні розглядає як RAW ака любий ієрархічний обьєкт в json, анемічний, який не має ніяких властивостей, типів, тощо: github.com/.../Document/0000000001.json
Далі він наділяє анемічну модель властивостями. Security, Pagination, Sync, Sort, Validation тощо.
Робить це в паралельних Dimensions. github.com/...bases/SocialNetwork/Users
На виході в нас анемічна модель User, навколо якої сформовано N layers, для того, щоб будь які операції з основним RAW документом приводили до виконування бізнесс логіки в N layers.
Чому цей підхід з Dimensions який будеє N layers навколо анемічного обєкта над потужний.
1. Код дуже добре читається. Різні прошарки бізнесс логіки не змішуються між собою, а існують, як би в паралельних вимірах (dimensions).
2. Він дуже добре розширюється. Ви починаєте з анемічної моделі, але згодом вона наділяється складною бізнес логікою, де моделі стають rich, без переписування (!) коду.
3. Пайплайн доменної моделі який побудований з Dimensions дуже швидко працює
Таким чином Fractal поєднує в собі гнучкість і простоту використання anemic моделей, які гармонічно еволюціонують в прогресивному стилі до rich доменних моделей.
В практичному плані це означає, що ви пишете в десятки раз меньше коду, зберігаючи гнучкість архітектури. Як цікаво, є купа прикладів де цілі соціальні мережі з нуля написані в
Ти якщо берешся за мою освіту (не знаю навіщо), роби це хоча б системно, а не на від**сь :) Механізми покращення durability в сучасних СУБД мають приблизно ніяке відношення до власне моделі даних (чим посгресовський WAL концептуально відрізняється від журналювання монги чи комітлогу кассандри, наприклад?). Чи ти маєш на увазі не апаратні збої, а баги на стороні апки (отже не «D» а «A» та/або «C»?)
Там все має значення. RDBMS з її ACID заточена щоб уникати як логічних так і апаратних помилок. Апаратні фіксяться за рахунок журналів, локів, ізоляції транзакцій. Логічні — за рахунок нормалізації в реляційній моделі данних. Тож, якщо ти перейдеш на Монго, Касандра або інший NoSQL, консистентність ти можеш втратити вже на рівні проектування бази данних. Наприклад будеш ссилатися в різних документах референцом на одну ж ту саму сутність, але на рівні ядра СУБД валідність цього референса ніяк не буде перевірятися.
Умовна система обліку підходить в якості прикладу набагато краще, бо подвійний (в ідеальному світі ще й імутабельний) запис — отже будь-яка бізнес-операція завжди транслюється в 2+ бухгалтерських транзакцій (проводок), і втрата якоїсь з них розвалює баланс.
ACID це не тільки про транзакції, а перш за все про те, як гарантувати цілістність СУБД при сбоях. Фінансові проводки в СУБД можуть бути, а можут і не бути, а ось FKs та інші Constraints в RDBMS є завжди.
Так мене переконувати не треба. Мені просто стало цікаво, чому як аргумент на користь ACID часто наводяться платіжні системи, які якраз історично є контр-аргументом — бо навіть в такій відповідній сфері як фінанси, виявляється цілком можливо побудувати надійну розподілену систему з елементів, які не забезпечують атомарності операцій як такої.
Все трошки складніше.
ACID забезпечує надійність вузла обчислень. Але не забезпечує надійність в рамках розподіленої системи (CAP теорема).
Але якщо ви відмовитесь від ACID на вузлах, ви фактично будете мати не один, а вже два рівні з проблемами. На рівні вузлу та на рівні синхронізації хостів.
Це сумно.
Я доречі код ще підрефакторив, він фактично зараз
або роботи на 3 хвилини
А ви пропонуєте купу іншого всього повстановлювати та зробити сайт, це ж зовсім інше, ясно що воно може бути й простішим по коду,
Сайт краще, оскільки ви його можете відкрити як на любому телефоні (андроід, епл) так і на компьютері.
Справа в них. Ви чомусь обговорюєте оптимізації, тому що вам не подобається, що щось в вас повільно завантажується і намагаєтесь перекласти відповідальність на ДДД.
Хто вам заважає не завантажувати весь доменний обєкт. Часткого кешувати, використовувати проксі патерн. Зберігати каунтер в паренті як я вже приводив приклад, зберігати лише айдішники і тільки їх рекурсивно обходити. Це якось суперечить ДДД ? Від того Task перестав бути доменним обєктом що вміє обробляти свої сабтаски мовчки ? Перестав мати бізнес логіку всередині себе? Наче ні.
То що ми зараз обговорюємо?