Обект на хранилище, услуга или домейн – къде е мястото на логиката?

Вземете този прост, измислен пример:

UserRepository.GetAllUsers(); UserRepository.GetUserById();

Неизбежно ще имам по-сложни "запитвания", като например:

//returns users where active=true, deleted=false, and confirmed = true
GetActiveUsers();

Имам проблем да определя къде свършва отговорността на хранилището. GetActiveUsers() представлява проста "заявка". Мястото му в хранилището ли е?

Какво ще кажете за нещо, което включва малко логика, като например:

//activate the user, set the activationCode to "used", etc.
ActivateUser(string activationCode);

person betitall    schedule 04.06.2010    source източник


Отговори (3)


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

ActivateUser работи върху един обект. Този обект трябва да бъде извлечен и след това модифициран. Хранилището отговаря за извличането на обекта от комплекта; друг клас ще отговаря за извикването на заявката и използването на обекта.

person Bryan Watts    schedule 06.06.2010

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

Бих предложил да прочетете книга като модели на корпоративна архитектура< на Фаулър /a>. В тази книга той обсъжда моделите, които споменавате. Най-важното е, че той възлага на всеки модел отговорност. Например логиката на домейна може да бъде поставена или в слоя на услугата, или в слоя на домейна. Има плюсове и минуси, свързани с всеки.

Ако реша да използвам слой на услугата, присвоявам на слоя ролята да обработва транзакции и оторизация. Харесва ми да го поддържам "тънък" и да няма логика на домейна там. Става API за моето приложение. Поддържам цялата бизнес логика с обектите на домейна. Това включва алгоритми и валидиране на обекта. Хранилището извлича и запазва обектите на домейна. Това може да е съпоставяне едно към едно между колоните на базата данни и свойствата на домейна за прости системи.

Мисля, че GetAtcitveUsers е добре за хранилището. Не бихте искали да извлечете всички потребители от базата данни и да разберете кои са активни в приложението, тъй като това би довело до лоша производителност. Ако ActivateUser има бизнес логика, както предлагате, тогава тази логика принадлежи към обекта на домейна. Запазването на промяната е отговорност на слоя хранилище.

Надявам се това да помогне.

person Joel Cunningham    schedule 04.06.2010
comment
В отговор на последния ви абзац: Ами ако продължаването на промяната Е единствената логика. напр. ActivateUser() просто актуализира един запис в таблицата User и един запис в таблицата ActivationCode. Това представлява ли логика? Ако не, какво прави? - person betitall; 06.06.2010

Когато изграждам DDD проекти, обичам да разграничавам две отговорности: хранилище и търсач.

Хранилището е отговорно за съхраняването на обобщени корени и за извличането им, но само за използване при обработка на команди. Под обработка на команди имах предвид изпълнението на всяко действие, извикано от потребителя.

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

Не считам търсачките за част от модела на домейна. Конкретните интерфейси на IXxxFinder се поставят в презентационния слой, а не в домейн слоя. Имплементацията както на IXxxRepository, така и на IXxxFinder се поставят в слой за достъп до данни, вероятно дори в един и същи клас.

person Szymon Pobiega    schedule 07.06.2010