@oop_ru

Страница 568 из 785
Mykola
22.03.2018
18:11:14
кстате, для изменения иммутабельных сущностей линзы всякие придуманы

https://habrahabr.ru/post/230649/

@fes0r ^ посмотри сам)

чего только функциональщики не придумают, чтоб их функциональщина работала)

Google
Roman
22.03.2018
18:20:33
@fes0r Как кстати лучше конструировать сущность, содерщащую VO? Передавать VO в конструкторе или сделать кучу параметров и внутри конструктора сущности самому собрать VO?

Mykola
22.03.2018
18:23:20
парвый вариант

Roman
22.03.2018
18:28:38
И ещё вопрос - а где лучше делать валидацию данных, которые я получаю извне? Только на уровне получаемых данных? Или внутри доменных сущностей тоже?

Bohdan
22.03.2018
18:29:00
поясни

Roman
22.03.2018
18:33:18
поясни
C# Предположим есть вот такой класс, описывающий простую сущность public class User { public User(string name) : this() { Name = name; } private User() { Id = 0; CreationDate = DateTimeOffset.UtcNow; } public long Id { get; private set; } public string Name { get; private set; } public DateTimeOffset CreationDate { get; private set; } }

Вот мне надо проверить имя при создании пользователя. Я могу навесить атрибуты на модель данных запроса, используемую для создания пользователя, а могу выполнять эту проверку в самом пользователе. Как лучше?

Типа вот такую модельку сделать для создания пользователя public class CreateUserViewModel { [Required] [MaxLength(200)] public string Name { get; set; } }

И выполнить все проверки разом и вернуть на фронт сразу пачку ошибок валидации

Uiiuviiw
22.03.2018
18:39:47
все зависит от того где с какого слоя модель юзер. но в любом случае, зачем валидатор м

vo засовывать?

кроме того зависит от самой вью, она может быть интерактивной и говорить что все неправильно при каждом символе

но валидировать должна модель создаёщая vo модели юзер

это если чисто архитектурно без привязки к реализации какого-то фраймворка

Google
Hell
22.03.2018
19:07:36
DI головоного мозга это когда не знаешь как можно жить без него?
это кода ты в порыве белой горячки для каждого класса делаешь выделение интерфейса

Sergey
22.03.2018
19:12:34
и не понимание что такое абстракция

Sergey
22.03.2018
19:13:05
ну и DI и DIP это разные штуки

для DI интерфейсы не нужны)

Roman
22.03.2018
19:16:42
все зависит от того где с какого слоя модель юзер. но в любом случае, зачем валидатор м
Юзер - это доменный объект. Операции с которым возможны только внутри обработчиков команд.

А вот CreateUserViewModel - это то, что приходит в теле веб-запроса (рассматриваем сценарий разработки WebApi)

Bohdan
22.03.2018
19:20:23
я завис вот на этой строчке и понял, что не помню шарп) public User(string name) : this()

Roman
22.03.2018
19:20:24
что значит "проверить имя"?
Проверить, что оно не null и что его длина не превышает 200 символов.

Sergey
22.03.2018
19:20:26
либо эти правила - часть валидации VO либо нет, в любом случае юзер про эти правила ничего не должен знать

Roman
22.03.2018
19:20:46
я завис вот на этой строчке и понял, что не помню шарп) public User(string name) : this()
Эта конструкция сначала вызовет дефолтный конструктор, а потом параметризированный

Bohdan
22.03.2018
19:22:25
ну вот твоя вью-моделька - это по суть объект запроса/dto от фреймворка до домена

Roman
22.03.2018
19:23:02
У нас есть атрибуты валидации, которые через рефлекшон работают. И можно разом провалидировать все входные параметры. И с точки зрения фронта это довольно удобно - сделал запрос и сразу полуил отлуп со списком всех свойств и описанием ошибок - где именно и почему эти данные не прошли проверку на корректность.

Sergey
22.03.2018
19:23:42
А может о них должна знать модель данных для создания юзера?
может, откуда я знаю что у тебя является инвариантами а что просто так

Google
Bohdan
22.03.2018
19:23:53
ну это разные проверки твоя сущность может иметь свои проверки (завязанные на какую-то бизнес логику)

Roman
22.03.2018
19:24:17
ну вот твоя вью-моделька - это по суть объект запроса/dto от фреймворка до домена
Ну не всегда. Что-то надо из роута достать, что-то из тела запроса, UserId вообще из контекста выполнения запроса берётся (куда его суёт мидлвара выполняющая валидацию токенов) - и всё это вместе собирается уже в команду, которая попадёт в обработчик.

Sergey
22.03.2018
19:25:12
http://gorodinski.com/blog/2012/05/19/validation-in-domain-driven-design-ddd/

Roman
22.03.2018
19:27:11
то, что собирается она не в одном месте, не делает ее не DTO :)
Ну вот с одной стороны Ъ DDD вэй - это внутри домена всё проверять. А с другой стороны - это ж не удобно фронту нифига. Ну вот отправил ты форму с 10 полей, 3 корректны, в 4м косяк - вот где внутри домена оно до этого поля прошло - всё выполнится, а дальше получишь сообщение о том, что мол у тебя вот тут ошибка. Поправил, а у тебя ещё потом выясняется что и в 6 поле ошибка и в 9. Но ты эти ошибки узнаёшь по-одной. И грустишь, проклиная автора системы за такое DDD.

Если на атрибутах сделать - то валидируется вся модель (DTO) сразу. Но вопрос - а надо ли тогда эту логику валидации дублировать в домене?

Bohdan
22.03.2018
19:27:57
@fes0r а вот твоя идея с валидацией запроса до его маппинга - как ложится на DDD? или она на это забивает?)

Sergey
22.03.2018
19:28:17
никак не ложится и даже не касается

Если на атрибутах сделать - то валидируется вся модель (DTO) сразу. Но вопрос - а надо ли тогда эту логику валидации дублировать в домене?
вот если подумать.... если мы дублируем логику валидации и у этой логики разные цели - одна реализация - что бы информировать пользователя, другая - что бы гарантировать консистентность состояния

Bohdan
22.03.2018
19:30:38
еще у меня крутится мысль о том, что в принципе валидация запроса (заполненность и простые ограничения) не всегда относится к домену

Roman
22.03.2018
19:33:37
еще у меня крутится мысль о том, что в принципе валидация запроса (заполненность и простые ограничения) не всегда относится к домену
Ну вот есть какое-то свойство класса, которое должно быть, скажем строкой с длиной не более 200 символов, так как в итоге это ограничение ляжет и на базу. Вот где эту проверку делать? В домене? В DTO запроса? И там и там? Или вообще забить и пытаться сохранить как есть, выплёвывая ошибку "Нишмогла я", когда мне провайдер БД скажет, что я пытаюсь инсертнуть строку, которая больше допустимого?))

Bohdan
22.03.2018
19:35:13
ну вот нет у меня сейчас ответа на этот вопрос) собственно об этом мысль и крутится... но еще никуда не выплыла

Roman
22.03.2018
19:36:32
Ну вот я сижу, пет проект делаю и задаюсь этим вопросом)

http://gorodinski.com/blog/2012/05/19/validation-in-domain-driven-design-ddd/
Дублировать валидацию получается?

Hell
22.03.2018
19:52:09
твоя реакция на тестовый ко

Bohdan
22.03.2018
19:52:56
твоя реакция на тестовый ко
корова? конь? кошелек?

Дублировать валидацию получается?
автор все же не раскрыл, как валидировать сложные штуки, завязанные на домене

Hell
22.03.2018
19:55:25
Roman
22.03.2018
19:56:23
автор все же не раскрыл, как валидировать сложные штуки, завязанные на домене
А ещё есть всякие бизнесовые штуки, типа того, что юзер может оформить заказ, только если сумма заказа не превышает разрешённого лимита, например. И такое в сущность уже не засунешь, а ошибку, если что-то пошло не так - вернуть как-то нужно.

Google
Bohdan
22.03.2018
19:56:48
наоборот, в сущность такое и ложится

но вот в слой валидации выносить не хочется

Roman
22.03.2018
19:57:02
А лимит этот в отдельном сервисе живёт

Bohdan
22.03.2018
19:57:38
так да, возможно хотя пример несколько натянутый

Roman
22.03.2018
19:57:45
Как и юзер

В сервисе, который отвечает за аутентификацию живут юзера, но есть данные, которые к аутентификации не относятся - профиль пользователя. Он тоже в отдельном сервисе. А оформление заказа в третьем. Вполне себе реальный кейс.

Bohdan
22.03.2018
19:59:48
что есть "сервис" у тебя?

Roman
22.03.2018
20:00:47
что есть "сервис" у тебя?
Приложение на ASP.NET Core.

Полноценный процесс со своими тредами и веб-сервером, перед которым ещё nginx стоит, и под которым отдельная базка лежит.

Они могут вполне себе и на разных машинах находиться, если куб так захочет.

Bohdan
22.03.2018
20:02:46
ну то есть у тебя микросервисы типа (вроде относительно адекватные) ну юзера + профиль можно на две сущности бить

Alan
22.03.2018
20:03:15
пользователь отдельно а customer = профиль с заказом вместе живут?

Bohdan
22.03.2018
20:03:58
Ну а профиль это ж не зона ответственности OAuth сервера.
ну потому и говорю про разбиение креды + профиль + кастомер допустим но это не по теме разговора

просто эта тема местной аудиторией уже в симфони чате обсуждалась

Roman
22.03.2018
20:05:51
просто эта тема местной аудиторией уже в симфони чате обсуждалась
Да суть не в этом. А в том, чтобы сделать некую операцию, мне нужно выполнить проверку, которая является чётким бизнесовым правилом. Но её нельзя засунуть в сущность)

Bohdan
22.03.2018
20:06:17
у меня тоже есть подобная беда) сейчас об этом задумался

Roman
22.03.2018
20:06:57
Тогда получается это какой-то сервис, живущий между сущностями и обрабочиками команд, который знает про инфраструктуру (какие сервисы подёргать, чтобы инфу собрать), ну либо не знает и ему инфу дают, но всё же, который живёт за пределами сущности.

Alan
22.03.2018
20:07:06
ну типа домен подтечет в инфраструктуру

Google
Roman
22.03.2018
20:07:29
ну типа домен подтечет в инфраструктуру
Ну вот как быть в такой ситуации?

Есть ещё один прикольный момент. Когда надо часть инфы из профиля, который живёт в другом сервисе, в момент выдачи токена - подгрузить, чтобы часть данных в id_token сложить (роли там всякие, телефоны, ФИО, мыло, чтоб на UI рисовать не дёргая никого). То есть сервис, отвечающий за аутентификацию начинает зависеть от сервиса профилей, доступ к которому осуществляется по токену. То есть OAuth сервис должен запросить токен сам у себя (!!!), чтобы дать его сервису профилей, чтобы тот его провалидировал у сервиса OAuth и выдал профиль по запросу, который этот OAuth сервис и делает))

Вот такой лолкек чебурек микросервисный

И одно без другого не работает

Но с другой стороны есть куча данных - типа тех же ролей, лимитов всяких, которые являются динамичными и рулятся юзерами через API, который этот сервис профилей предоставляет. То есть просто совместить эти 2 сервиса неправильно, так как сервис, отвечающий за аутентификацию реализует только её и больше ничего.

Alan
22.03.2018
20:13:46
ну там где профили это oauth server ? он же и ответит данными клиенту в соответствии со скоупом и запрашиваемыми полями, вместо него наверно можно представить другой oauth сервер

тут oauth изолирует их нет?

Anton
22.03.2018
22:12:28
Такое случается когда нет понимания что есть пользователь, а что аккаунт

Anton
22.03.2018
22:13:55
ИМХО складывать инфу в токен надо не для того что бы на клиенте эту инфу читать.
Яростнг плюсую. Хотя может это говорит во мне виски...

Bohdan
22.03.2018
22:14:27
Roman
22.03.2018
22:14:30
виски он вообще умный...
Особенно односолодовый)

Bohdan
22.03.2018
22:15:18
Ну драсте, id_token для этого и придумали
то, что что - то для чего - то придумали - не значит, что так нужно делать

Страница 568 из 785