Обновить
61

Architect | Lead | Senior Developer

0,7
Рейтинг
13
Подписчики
Отправить сообщение

Я хочу попробовать интерфейс по двум причинам - чтобы не делать маппинги и, когда добавляется новое поле, компилятор скажет в каких DTO я забыл его добавить.

Это смотря как посмотреть.

Вот например бег по земле (в воздухе), бег на мелководье и бег по дну бассейна.

Чтобы сохранить одну и ту же скорость - нужно затратить тем больше энергии, чем более вязкая среда. Другой пример - со скоростью света в вакууме (300 тыс км/с) и в алмазе (124 тыс км/с) - секунда тут одна и та же. Зависимость от энергии, а не от времени. Хотя и есть школьная формула, которая связывает скорость, время и расстояние.

От чего еще может зависеть скорость? Вот как я выяснил на своем опыте - от внутренних физических и химических реакций в мозге и теле. Секунда на видеорегистраторе - все еще "общепринятая" секунда, но мой мозг за эту секунду успел больше, чем обычно - и распарсить картинку из глаз, принять решение, подать команду мышцам руки - и это ощущалось как slo-mo. Потому что трактор или соседняя машина так и ехала, как она ехала в той физической среде, но в моих глазах это все замедлилось.

Если перейти теперь к теории относительности - вот это все замедление времени, если приближаться к скорости света. Фотон летит уже со скоростью света - то есть время для него 0 и расстояние тоже 0. Если смотреть "из его глаз" - он как бы мгновенно долетает от Солнца до Земли (тут кстати еще интересный момент - означает ли это, что с точки зрения фотона Солнце и Земля находятся в одной точке пространства). И что если это не фотон "быстрый" / "энергичный", а все остальное - "медленное" / "вялое" ? И поэтому для всего остального появляется такие вещи как расстояние и время? И для которых человечество придумало средство измерения (линейка и часы).

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

Да, сейчас у меня этот вариант, но на интерфейсах

// Domain level

public interface ICreateOrder
{
  string Number { get; set; }
  DateTime Date { get; set; }
  // еще 100 500 полей
}

public class Order
{
  string Number;
  DateTime Date;
  // еще 100 500 полей

  public Order(ICreateOrder dto)
  {
    // маппинг полей
  }

  public Update(IUpdateOrder dto)
  {
    // маппинг полей
  }
}

// Application level

public class CreateOrderDTO : ICreateOrder
{
  public string Number { get; set; }
  public DateTime Date { get; set; }
  // еще 100 500 полей
}

Ага, вот с кодом понятней. Так выходит что

  1. В сущностях не все поля, а только "сложные" / с логикой и они имеют публичный set, но с IsSealed "оговоркой"

  2. DomainData - это по сути DTO (придет из контроллера), содержит все поля, с публичными set, но с тем же успехом может быть классом для ORM, с маппингом на таблицу в БД

И логика следующая

  1. Когда надо создать заказ - у нас есть DomainData, там все поля открыты, делаем валидацию и сохраняем в БД через ORM например

  2. Когда позже начинаем работать с предметной областью - достаем из БД запись, конструируем DomainObject, там будет только часть полей, которые нужны для конкретных сложных бизнес случаев. По идее даже можно сделать их несколько штук, под каждый или группу UseCase, чтобы не делать один god класс, или сделать эту штуку интерфейсом.

Другими словами тут комбинация анемичной модели и богатой.

Да, действительно, разницы нет. При конструировании сущности из БД - моя ORM умеет работать с приватными полями - а это и есть технических хак.

Либо конструктор, либо фабрика, либо фабричный метод

К сожалению я все еще не вижу решения - как это на самом деле работает.

Может давайте псевдо кодом?

public class Order
{
  string Number;
  DateTime Date;
  // еще 100 500 полей

  public Order(/* 100 500 полей*/)
  {

  }

  // 100 500 методов
  public void UpdateXXX()
  {
    
  }
}
public class CreateOrderDTO
{
  public string Number;
  public DateTime Date;
  // еще 100 500 полей
}

Допустим будет фабрика

public class OrderFactory
{
  public Order Create(CreateOrderDTO dto)
  {
    // Валидация DTO (поля публичные - проблем нет)

    // Вот тут у вас что?
    // Так?
    return new Order(dto.Number, dto.Date, /* остальные 100 500 полей из DTO*/)
  }
}

Сразу не увидел этот коммент.

В нашей практике, маппинг дто на доменные объекты происходит в простом случае в коде дто. Мы просто делаем метод что-то вроде dto.toDomain(), внутри которого вызываются конструкторы или фабрики домена, и обратный статический Dto.from()

Это все еще не раскрывает решения проблемы маппинга. Свойства у сущности имеют private set? Как тогда маппинг, если они приватные?

Ну нет же, у меня приходит CreateOrderDTO из контроллера, в БД еще ничего нет. Мне надо валидировать DTO, создать сущность, запустить некоторые сложные процессы (путем отправки события "создан заказ") и сохранить это в БД. И в данный момент проблема с "создать сущность" из этого DTO, так как у сущности все свойства имеют private set.

Вот, много текста и там ниже еще коммент ваш, давайте постепенно разберемся.

Значит, первое - я имел ввиду не про конструирование сущности из БД, а про use case "создание заказа" или "обновление заказа" или "отмена заказа".

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

Далее, да вот я вычитал BestPractice - что сущность должна сама проверять свое состояние. То есть это свойства закрытые от изменений из вне (public get + private set).

Таким образом, чтобы в use case "создание заказа" мне создать заказ из DTO, где куча полей - все эти поля нужно добавить в конструктор. Аналогично, чтобы в use case "обновление заказа" изменить поля - надо нагенерить кучу методов UpdateXXX(). И да, некоторые из них (update заметки) будут просто проверять, например, длину значения (не более 255 символов), а некоторые (update статус) - будут запускать сложные процессы. Пожалуй даже вместо UpdateStatus лучше сделать методы Approve() или Cancel().

И вот мне эта тема с кучей параметров в конструкторе и кучей методов UpdateXXX не нравится.

Далее из вашего комента ниже

MediatR-style, для каждого useCase делаем команду и ответ.

Команды уже с доменной сущностью (это уже Application)

Это не решает проблему. Просто перекладываем из одно места в другое. Там все равно будет та же сущность с кучей параметров в конструкторе и кучей методов UpdateXXX. И все еще как-то надо подружить DTO и сущность.

AutoMapper поддерживает вложенные обьекты

Тут не совсем понятно - вложенные - это вложенные (они могут приватными и публичными) или приватные? Скорее всего приватные. Мне надо время, чтобы понять что вы написали. Отвечу чуть позже. Видимо у вас свойства сущности все же приватные, но вы в обход этого мапите их с использованием технического хака.

Эмм, технически можно, но по логике - нет потребности. Просто есть use case "создание заказа" или "обновление заказа" или "отмена заказа".

Нет, подковырки нет, у меня реально стоит вопрос, я тут решил изучить наконец-то DDD на примере моего реального сложного проекта, который сделан по анемичной модели. И там возникает куча вопросов что и как делать.

Да, мы уже общались в коментах по другой статьей )) - у вас table module.

И дружеское напоминание - речь идет не про конструирование сущности из БД, а про use case "создание заказа" или "обновление заказа". Когда DTO приходит извне.

@RakovskyAlexander у вас тоже спрошу - вот есть у вас заказ, там 100500 полей (от номера и даты до суммы, тегов, заметок и прочего). Когда создаете сущность - как вы передаете все эти 100500 полей из ДТО, которое пришло из контроллера (адаптера)? Еще одно ДТО на уровне Domain или в обшей DLL и маппинг между ними? Все 100500 полей пихаете в конструктор? Какой либо еще вариант?

Я тоже склонен считать, что времени не существует.

Я несксолько раз по жизни замечал моменты, что я воспринимаю все как бы в замедленной съемке - обычно это были какие-то критические моменты. Но все это было крайне субъективно, длилось меньше секунды и не было никакой внешней точки отсчета.

Пока я чуть не попал в ДТП и в машине был видеорегистратор. В тот момент у меня так же возникло ощущение slo-mo как в Макс Пейне, я увернулся, но у меня была запись с видеорегистратора, что является наиболее объективным "взглядом", с внутренним "общепринятыми" часами (накладывает на видео) и по сути внешняя точка отсчета.

В моем мозгу и в глазах я видел это так - едет трактор, у него отваливается колесо, ковш начинает описывать дугу, и я резко выворачиваю руль. На видео регистраторе - тоже самое, только между колесом и ковшом прошло крайне мало "общепринятого времени" (там можно было по кадрам разложить, но я этого не делал).

По итогу я сделал вывод, что это не время ускорилось (на видео - все другие события происходили с "нормальным" течением времени), а это в следствие каких-то физических/химических причин мой мозг включил буст на доли секунды и ускорил протекание реакций и мыслей внутри себя. Из-за чего и возникло ощущение slo-mo.

Ну и по результатам у меня появились следующие мысли:

  1. Есть максимальная физическая скорость протекания реакций внутри организма - ну например скорость электрического сигнала по нервной системе. То есть по сути скорость света в среде (в вакууме 300 тыс км/с, в алмазе насколько я помню 124 тыс км/с). И относительного того критического момента - все наоборот, я 99,99% живу как бы замедленный, но теоретически мог бы всегда жить в режиме буста

  2. Времени нет, есть скорость - скорость изменения положения в пространстве, скорость внутренних реакций, скорость заполнения в пространстве (растущее дерево никуда не движется само по себе, но заполняет пространство своим ростом)

  3. У человека есть некое внутреннее сознание и память, что в целом позволяет анализировать относительность бытия.

  4. И думаю, именно память повлияла на появление понятия "время". Я представил, если бы человек не помнил ничего - то откуда бы он знал, что у него есть "прошлое"

  5. В силу наличия этого "прошлого" в памяти, "будущего" в мыслях ("встретимся через два часа"), человечеству понадобился некоторый удобный, общепринятый для всех, стабильный и равномерный механизм определения относительности событий. И так человечество придумало часы - сначала это были солнечные. И очевидно, что если бы планета вертелась вокруг солнца быстрее или медленней - человеческий "квант" времени был бы совсем другим. Затем песочные (на основе гравитации) и в итоге кварцевые и даже атомные. Но все эти штуки - это не время, это все еще скорость движения в пространстве. Песок "падает вниз" с определенной скоростью, а кристал кварца вибрирует (двигается) с определенной частотой. А люди просто привязали как якорь свою память на события к тому или иному способу движения в пространстве.

А вы с чем сравниваете?

У меня до этого был hp spectre 360 13.3, сейчас lg gram 16. По батарейке lg когда был свежим (2021 год) хватало на примерно 6 часов рабочего дня - это обычная работа программистом (покодить, сбилидть, запустить в отладке). Сейчас часа 4.

На новом HP в том же режиме хватало немного меньше (часа 4-5).

На lg проц мощнее (i7 против i5) и экран больше. Мне не очень верится, что есть ноут, который реально проработает рекламируемые 10-12-20 часов именно в рабочем режиме. (Поправочка - тонкий и легкий, а не кирпич 3 кг, где 2.5 это батарейка)

Зачем давать столько имен одному и тому же? Тех лид - это тогда кто? Он круче принципала? Почему dev ops превращается в архитектора? Их минимум четыре штуки - энтерпрайз, солюшен (который работает на уровне C4 и спецификаций API), системный, данных / DWH. Вот где все эти люди?

Lg gram - 16 дюймов и 1.2 кг веса, 14 и 1 кг - вот это действительно ультрабук

А как вы сохраняете очереди из акторов в хранилище, чтобы восстановиться после сбоев?

А вы где храните table module?

У меня проблема не с orm, а с DTO, которое должно быть доступно и для уровня сервисов и для уровня домена. У меня это две разные DLL.

Информация

В рейтинге
2 343-й
Откуда
Россия
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Архитектор программного обеспечения
Старший
C#
.NET Core
SQL