BG Development


  Reply to this topicStart new topicStart Poll

> DDD сийдване на Enumeration class
relax4o
Публикувано на: 31-08-2022, 22:12
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2670
Регистриран на: 04.04.07



Здравейте, преди всичко да кажа - наясно съм, че ДДД няма общо с .НЕТ или който и да език, просто best practices в различните езици донякъде се различават като имплементация, а аз отдавна не съм писал на .НЕТ и сега ми се налага да прилагам дизайн, с който не съм толкова наясно използвайки език, с който не съм боравил много. Идеалният проект да практикувам - въпроса е, че все пак на работа се очаква да действам по-бързо.

Въпроса ми е следният. Добра практика ли е да се сийдват enumeration classes в базата данни?

Създавам микросървиз, който ще се занимава с обработката на пропъртита (апартаменти, къщи и т.н.).

Едно пропърти има страшно много детайли, като някои от тези детайли са списък от предефинирани стойности (дропдаун менюта), които вероятно никога няма да се променят или ще е много рядко.
Поради тази причина се разбрахме, че няма смисъл да се позволява добавянето им отвън.

Предвид тази информация сметнах, че използването на енумерация в този случай има логика.
Но все пак тези стойности искам да са и в базата данни като lookup tables и от тук идва въпроса ми дали е добра практика да се сиийдват при стартиране на сървиза?

Другият въпрос ми е, има ли нещо нередно, ако една енумерация съдържа много стойности. Например да вземем Property Type. В UK имат страшно много типове - вероятно около 50-60 (които ще се опитаме да ги намалим).

От друга страна тези типове вероятно ще имат родител (т.е. повече информация ще държат) и от там се замислям дали да е Entity или енумерация.

Все още ми е трудно да определям кое какво да е и как е по-добре да се структурира в ДДД света.

Като цяло никъде не намирам информация относно това и ми се струва, че или съм се насочил в грешната посока, или прекалено много се фокусирам в дребен имплементационен детайл.

Благодаря предварително.


--------------------
Бисери :D

QUOTE (oveRLuckEd)
Ползваш някоя нова версия на PHP, която е вече ооп ориентирана и заради това ти я изкарва тази грешка.


QUOTE (nbacool2)
Щом няма input полета, значи няма откъде да се направи SQL инжекция Very Happy
PM
Top
thrawn
Публикувано на: 01-09-2022, 14:38
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3388
Регистриран на: 17.01.17



Какво значи "да се сидват при стартиране"?
Щом ще могат да се променят тия данни (независимо колко рядко), то задължително клиентите трябва да ги получават от някъде. Вариант с твърдо кодирани в клиент стойности е несериозен. Това значи, чв сървизът трябва да ги предоставя при поискване. От тук можеш да помислиш за някаква форма на кеширане в клиентите, за да спестиш излишен трафик.

Иначе, всяка база данни поддържа подобни типове данни (enum) така че, тук няма проблем. Но за мен, по-добрия вариант на реализация е с употребата на таблица (lookup) още повече, че предвиждаш дървовидна структура.
PMEmail Poster
Top
relax4o
Публикувано на: 01-09-2022, 16:32
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2670
Регистриран на: 04.04.07



Идеята е погледнато от кода да е Enumeration клас.

Примерно:

CODE

public class TenureType : Enumeration
{
   public static readonly TenureType Freehold = new(1, nameof(Freehold));
   // и други предефинирани типове

   private TenureType(int id, string name)
       : base(id, name)
   {
   }
}


Enumeration е абстрактен клас, който предлага повече функционалности от вградения enum тип и е по-flexible. https://ankitvijay.net/2020/05/21/introduct...meration-class/ малко повече информация.

Този TenureType (и още доста други) е част от Property entity-то, което ще е конфигурирано (използвам EF Core в случая, но това не е важно) да взима само ID-то от този обект. Съответно при извличане, ще го обръща в такъв.

Идеята ми тука е, че тези предефинирани стойности да са представени като енум в кода и lookup таблица в базата данни именно поради нуждата, че ще трябва да ги представям на клиентите + че ако се налага да ръннвам ръчни куерита (поради каквато и да е причина) тези ID-та да придават смисъл в базата данни.
А причината да искам да са под формата на енумерация е, че тези данни има голям шанс да трябва да се мапват към други стойности за изпращане към друг сървиз.

Под сийдване при стартъп, имах предвид, че при инициализиране на сървиза (след деплойване), едно от първите неща да е да вземе всички стойности на енумерацията (Enumeration класа предоставя GetAll(), който връща списък от стойностите) и де факто да ги запиша в базата данни.

По този начин, понеже говорим за ДДД и домейна е движещата част, ще е сигурно, че бизнес логиката ще работи с правилни данни.

От една страна ми се струва удобно понеже кода и базата данни ще са винаги синхронизирани от към възможни стойности.

От друга не ми се струва толкова добра идея, особено ако трябва да се махат стойности от списъка. Тогава е опасно от гледна точка, че без да искаме може да докараме данните до невалиден стейт (дори и ако добавим constraints) и да чупим всичко.

Дори, ако забравя за сийдване при стартъп, то какъв вариант използвате, за да подсигурите, че кода ви (при използване на lookup данни) ще е синхронизиран особено, когато трябва да знаете конкретните типове?

В една стара система писана на PHP, например, в момента има една голяма lookup таблица с всякакви данни (много лош дизайн, който мразя), които си имат и "код", който референсираме чрез създаване на безброй именувани константи, за да премахнем разните ID-та, които не ни говорят нищо в кода. В тази система в момента вкарваме нови стойности чрез ръчно писани миграции. Имаме и админ панел за тази цел, но не го ползваме и затова и не искаме в новия продукт да правим нещо, което няма да се ползва (и не трябва да се полазва).

Иначе следвам имплементацията на Microsoft и ще дам няколко линка, за да покажа за какво точно говоря.

CardType.cs - Enumeration class
CardType entity configuration - за създаване на lookup таблица
CardType seed on startup


Съжалявам за дългите постове, но се опитвам да дам колкото може повече информация дори и да се окаже накрая безсмислена тема. icon_lol.gif

Това мнение е било редактирано от relax4o на 01-09-2022, 16:37


--------------------
Бисери :D

QUOTE (oveRLuckEd)
Ползваш някоя нова версия на PHP, която е вече ооп ориентирана и заради това ти я изкарва тази грешка.


QUOTE (nbacool2)
Щом няма input полета, значи няма откъде да се направи SQL инжекция Very Happy
PM
Top
thrawn
Публикувано на: 02-09-2022, 07:57
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3388
Регистриран на: 17.01.17



Постановката не ми изглежда добре.

Основния проблем е, че enum (и всички производни) дефинират неизменяем, логически свързан сет от константи. Основното тук е, че целия сет е ясно дефиниран при създаването на самия модул. Когато използваш enum и искаш базата данни да следва същия модел (DDD) то изборът е udt имплементация (каква точно зависи от базата данни) а не lookup таблици (които практически се явяват заместител).

Тук вече идваме и на основния проблем. Изтриването на елемент ще рефлектира на history данните в базата данни (там ще останат дупки). Така че, или трябва да замениш елемента с друг (практически обезсмисля триенето) или да изтриеш съответните данни (като цяло, лоша идея). Та единствената възможност при подобна структура е единствено да добавяш елементи.

Синхронизирането на код и база данни задължително тряба да минава през версия на базата данни, независимо дали ще ползваш udt или lookup таблици. Като моя съвет е, ръчно да си пишеш sql-а за ъпгрейд от една версия до друга.

При теб обаче, още от сега е ясно, че enum стойностите подлежат на прмяна (независно от това, колко рядко ще се случва това). Така че, всичко горе е лошо като идея. Трябват ти lookup таблици със съответните CRUD интерфейси към тях и коректни ограничения гарантиращи цялостта на данните в самата база данни. Опитът автоматично да обновяваш базата данни при пробмяна на константи в приложението (след поредния билд) няма да ти спести нищо, а ще създаде много повече проблеми (не съвместимост между архиви на базата данни, невъзможност зьа работа по/с различни версии на приложението и т.н.).

Щом държиш да си DDD, се води по домейна на базата данни и зарежи тия глупости, че кодът е първи.

QUOTE
В една стара система писана на PHP, например, в момента има една голяма lookup таблица с всякакви данни ...

Това е в следствие на работа с нетипизирани езици. За всяка логически свързана група от данни ти трябва отделна таблица (таблици). В продивен случай няма как да гарантираш цялостта на данните си.

Това мнение е било редактирано от thrawn на 02-09-2022, 08:01
PMEmail Poster
Top
0 потребители преглеждат тази тема в момента (0 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0