powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / DDD разнесение кода логики по классам
25 сообщений из 169, страница 2 из 7
DDD разнесение кода логики по классам
    #39910396
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt

Эрик говорит про слои (или уровни) архитектуры, а не про ООП или классы.
В его книге об этом чётко и подробно расписано.

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

hVostt

Ты в реале такое же упоротое быдло, или только тут так себя по-свински ведёшь?

с уродцами типа тебя по другому нельзя, ты человеческого языка в принципе не понимаешь
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910423
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford
мда, у тебя отсутствуют совершенно базовые знания о разработке, уровни, про которые он говорит как раз и содержат в том числе доменные сущности, которые и обладают логикой (последняя цитата по ссылке там напрямую их упоминает), если-бы ты узнал об этой книжке не сегодня из этого топика, а хотя-бы слышал о ней в прошлом, то этого чудовищного бреда бы не нес, обычно даже джуны более подкованы в базовой теории, я честно говоря не разу не видел джуна, который обладал-бы насколько извращенным пониманием ООП


По сути ничего нет и не было с самого начала.
Откопал статью времён мамонта, вместо какой-либо аргументации.
Чисто детское авторитарное мышление "потому что он так сказал".

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

И я не утверждал, что только вот так и никак иначе правильно, а делился своими соображениями и опытом, для этого форум и существует.

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


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

Ну и с новым годом тебя, ты жалок.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910426
Hexag0v
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVosttлогики агрегатах быть не должно. ни в корне, ни в сущностях.
hVostt
Кому действительно интересно как используется CQRS вместе с DDD, можете ознакомиться со следующими материалами:

Применение в микрослужбе упрощенных шаблонов CQRS и DDD



Там как раз написано:

авторВ рамках DDD изменять сущность желательно только с помощью методов самой сущности

И пример класса, в котором видно, что модель имеет логику, следственно это не анемичная сущность.
И в целом, там не рекомендуют анемик, а как раз логику в агрегатах.

автор
Код: c#
1.
2.
3.
4.
5.
6.
public class Order : Entity, IAggregateRoot
{
    public void AddOrderItem(int productId, string productName,
                            decimal unitPrice, decimal discount,
                            string pictureUrl, int units = 1)
    {




https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/microservice-domain-model

авторHowever, if you need to tackle the complexity of a microservice’s domain that has a lot of ever-changing business rules, the anemic domain model might be an anti-pattern for that microservice or Bounded Context. In that case, designing it as a rich model with entities containing data plus behavior as well as implementing additional DDD patterns (aggregates, value objects, etc.) might have huge benefits for the long-term success of such a microservice.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910428
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hexag0v,

Всё верно :)

Я дал информацию для более полного раскрытия темы, а не только с одного бока, как лично я считаю.
В двух проектных командах пробовали использовать такой подход, плюс общался с коллегами, активно применяющими DDD, плюс изучал исходники других проектов.

Из полученного опыта могу сказать, что несмотря на красоту изначальной идеи, на практике почти никаких плюсов в инкапсуляции логики в классы сущностей и агрегатов нет. А минусов вагон.

Ситуаций, когда это действительно может принести профит прям ничтожно мало.

Если убрать это требование, никаких противоречий нет. Так называемая "анемичность" это искусственный термин, и довольно странный. Никаких проблем нет в реализации всех артефактов из DDD, включая полноценный ubiquitous language без необходимости городить чудовище из классов модели.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910438
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hexag0v,

Для примера можно рассмотреть вот этот код

https://github.com/dotnet-architecture/eShopOnContainers/blob/7b300ec91244bf44bf82372389d362a98c2da8b6/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
{
    using Domain.AggregatesModel.OrderAggregate;
    using global::Ordering.API.Application.IntegrationEvents;
    using global::Ordering.API.Application.IntegrationEvents.Events;
    using MediatR;
    using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
    using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
    using Microsoft.Extensions.Logging;
    using System;
    using System.Threading;
    using System.Threading.Tasks;

    // Regular CommandHandler
    public class CreateOrderCommandHandler
        : IRequestHandler<CreateOrderCommand, bool>
    {
        private readonly IOrderRepository _orderRepository;
        private readonly IIdentityService _identityService;
        private readonly IMediator _mediator;
        private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
        private readonly ILogger<CreateOrderCommandHandler> _logger;

        // Using DI to inject infrastructure persistence Repositories
        public CreateOrderCommandHandler(IMediator mediator,
            IOrderingIntegrationEventService orderingIntegrationEventService,
            IOrderRepository orderRepository,
            IIdentityService identityService,
            ILogger<CreateOrderCommandHandler> logger)
        {
            _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
            _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
            _orderingIntegrationEventService = orderingIntegrationEventService ?? throw new ArgumentNullException(nameof(orderingIntegrationEventService));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        public async Task<bool> Handle(CreateOrderCommand message, CancellationToken cancellationToken)
        {
            // Add Integration event to clean the basket
            var orderStartedIntegrationEvent = new OrderStartedIntegrationEvent(message.UserId);
            await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStartedIntegrationEvent);

            // Add/Update the Buyer AggregateRoot
            // DDD patterns comment: Add child entities and value-objects through the Order Aggregate-Root
            // methods and constructor so validations, invariants and business logic 
            // make sure that consistency is preserved across the whole aggregate
            var address = new Address(message.Street, message.City, message.State, message.Country, message.ZipCode);
            var order = new Order(message.UserId, message.UserName, address, message.CardTypeId, message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration);

            foreach (var item in message.OrderItems)
            {
                order.AddOrderItem(item.ProductId, item.ProductName, item.UnitPrice, item.Discount, item.PictureUrl, item.Units);
            }

            _logger.LogInformation("----- Creating Order - Order: {@Order}", order);

            _orderRepository.Add(order);

            return await _orderRepository.UnitOfWork
                .SaveEntitiesAsync(cancellationToken);
        }
    }


    // Use for Idempotency in Command process
    public class CreateOrderIdentifiedCommandHandler : IdentifiedCommandHandler<CreateOrderCommand, bool>
    {
        public CreateOrderIdentifiedCommandHandler(
            IMediator mediator,
            IRequestManager requestManager,
            ILogger<IdentifiedCommandHandler<CreateOrderCommand, bool>> logger)
            : base(mediator, requestManager, logger)
        {
        }

        protected override bool CreateResultForDuplicateRequest()
        {
            return true;                // Ignore duplicate requests for creating order.
        }
    }
}



Это команда для создания заказа.
Здесь мы видим DDD и CQRS в чистом виде.
Почти.

Особенности ООП и конкретных языковых средств не дают возможности провести эту операцию исключительно на уровне DDD.

Если отказаться от CQRS и команд, где разместить код создания заказа?

Как видим, это целый комплекс различных операций, относящихся как бизнес-логике, так и к инфраструктуре. Это работа с репозиторием, публикация событий, и сохранение через UOW.

Конструктор использовать нельзя, так как во-первых, он не может быть асинхронным, во-вторых логика в конструкторе -- зло, в третьих, DDD должен быть отстранён от деталей реализации, от хранилища, событийной системы и т.д. Хотя следуюя принципам ООП, именно конструктор является самым лучшим местом для реализации создания и конструирования экземпляра предметной области, чтобы поддерживать свой инвариант.

Тогда нам понадобится что-то вроде фабрики. Ну а это уже ни что иное, как сервис.

Далее. А что делать, если поддержать полностью валидный инвариант при изоляции на уровне агрегата нельзя? Именно так чаще всего и бывает. Значит в экземпляр агрегата необходимо прокинуть полный доступ хотя бы к ограниченному контексту. Задача далеко не из простых, сделать это органично и не нарушая парочку известных принципов разработки.

Далее. А что делать, если нам нужна операция, затрагивающая несколько агрегатов, в которой сложно чётко выделить явный корень агрегата операции? Например, создание резерва при создании заказа, с обеспечением гарантии оплаты из спектра возможных гарантов (депозит, блокировка суммы, гарантийное письмо и т.д.). В каком агрегате будет красивый заветный метод?

Далее. А что делать, когда подключили интеграцию с партнёром и он грузит такие заказы огромными пачками, десятки, сотни тысяч за раз, и партнёров много становится. И профилирование показывает жестойшее узкое место в этой команде? И ничего поделать нельзя, нельзя трогать DDD.

Далее. Ну а как же протестировать вот именно эту команду? Без учёта логики, инкапсулированной в домен (order.AddOrderItem)? Никак, ведь это классы, а не интерфейсы. Да ещё и экземпляры создаются через конструктор. Выходом может быть запрет использования конструкторов, и требование помечать публичные методы сущностей как virtual. Это позволит решить задачу, но какой ценой!

Далее. Мы видим вот такой код:

Код: c#
1.
2.
     var address = new Address(message.Street, message.City, message.State, message.Country, message.ZipCode);
     var order = new Order(message.UserId, message.UserName, address, message.CardTypeId, message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration);



Выглядит приятно. На первый взгляд. До первых требований от бизнеса. До первого рефакторинга. Внести изменения в адрес теперь безумно дорого, даже если изменения будут обратно совместимыми. Чтобы безболезненно расширить сущность, необходимо будет создать новых констуркторов. Что очень вредит DDD, теперь преимущества единого языка уже не выглядят такими замечательными, на фоне того, когда у вас несколько вариантов сделать одно и то же, так какой же нужно использовать?

Можно и дальше продолжать, взять другие примеры.
Как ни крути, логика будет размазана, ООП здесь не всегда работает. Изоляция очень примитивная и больше мешает, чем помогает.

Как исправить?

  • Убираем логику изменения из моделей, и переносим в команды, а бизнес-логику в службы/сервисы, -- при чём, желательно не нарушать принципы разработки ПО, делать сервисы узко специализированными.
  • На уровне команд и только в них вносятся изменения домен: создаются, изменяются классы агрегатов и сущностей, контролируются инварианты, проводятся саги и т.д.
  • Команда может выполнить свою задачу как угодно, в том числе и через внесение изменений наиболее оптимальным образом, не нарушая никаких принципов и не попирая ни чьи идеи.
  • Команда может контролировать инварианты более широко и глубоко, обращаться к любым внутренним и внешним сервисам, выполнять запросы, создавать вложенные команды, таким образом поддерживается декомпозиция логики.
  • Можно создавать новые команды, не внося изменений в домен, что прям очень хорошо.
  • Не нужно выдавливать из ООП то, для чего он не был изначально создан, и жить с ограничениями реализации ООП конкретного языка.
  • Не нужно зависить от языковых средств. Один и тот же подход прекрасно может быть реализован на различных языках.
  • Теперь позволительно шарить логику домена для уровня презентации, например, валидацию.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910447
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ещё дополню. В таком варианте исполнения, значительно вырастает роль UOW в системе.

В приведённом примере коммитится только сохранение данных в хранилище, что не делает всю операцию строго атомарной. Выпуск событий может быть только в случае успешного выполнения и завершения операции. Потом захочется сохранять ещё и сами успешные команды в некое хранилище. А если мы используем EventSourcing, нам понадобится особый класс событий и хранилище этих событий, которое уже, на минуточку, является хранилищем мастер данных. Хорошо бы иметь возможность выполнить серию команд в одной транзакции и получить полностью согласованный результат. Не хотелось бы разруливать заморочки с блокировками на уровне команд.

В итоге, сохранение UOW лучше вынести за пределы команды. Все события, изменения данных и команды, которые инициировали изменения, записываются в UOW. При сохранении, всё персистится, события публикуются, а на выходе мы получаем согласованный, стабильный и ожидаемый результат.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910449
Hexag0v
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVosttКонструктор использовать нельзя, так как во-первых, он не может быть асинхронным, во-вторых логика в конструкторе -- зло
Сложной логики с участием IO там быть не должно, в для простой асинхронность не нужна.

hVosttА что делать, если поддержать полностью валидный инвариант при изоляции на уровне агрегата нельзя?
Тут не понял.

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

hVostt А что делать, когда подключили интеграцию с партнёром и он грузит такие заказы огромными пачками, десятки, сотни тысяч за раз, и партнёров много становится. И профилирование показывает жестойшее узкое место в этой команде?
Это может быть с любым методом, любого класса, каждый случай нужно рассматривать отдельно.

hVosttНу а как же протестировать вот именно эту команду? Без учёта логики, инкапсулированной в домен (order.AddOrderItem)?
Тестировать отдельно класс Order, через метод GetTotal() например, в чем тут проблема?

В целом не вижу особых проблем с указанной командой.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910450
Hexag0v
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt
Хорошо бы иметь возможность выполнить серию команд в одной транзакции и получить полностью согласованный результат.


Не факт, что CQRS подходит для большого количества зависимых операций.

Фаулер писал на эту тему:
авторLike any pattern, CQRS is useful in some places, but not in others. Many systems do fit a CRUD mental model, and so should be done in that style.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910474
17-77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford

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

так приведите конкретный пример хорошего использования DDD, только не пет проект, высосанный из пальца, а реально сложную предметную область, банки там, страхование или типа того, мне правда очень хочется посмотреть как использовать DDD, чтоб не наступить на тыщу граблей и чтоб сохранить солид и не делать god-объектов

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

а от сторонников я только и слышу - "не умеешь правильно готовить", ну так покажите как надо
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910479
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford
очередной поток сознания от местного "эксперда", нагугленные умные слова сваленные в кучу без малейшей попытки осмысления и опыта практического использования

у hVostt хотя бы есть несколько лет разработки проекта на CQRS + ES с нуля
а у вас что есть, кроме какашек для вентилятора?
Можно и повежливее в топики врываться, коли не обезьяна
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910496
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt

По сути ничего нет и не было с самого начала.
Откопал статью времён мамонта, вместо какой-либо аргументации.
Чисто детское авторитарное мышление "потому что он так сказал".

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

И я не утверждал, что только вот так и никак иначе правильно, а делился своими соображениями и опытом, для этого форум и существует.


т.е. дошло наконец что классический DDD из себя представляет? Сутки потребовались, Эрик Эванс у него такого не говорил, конечно если ты это имя только вчера услышал. Если речь про DDD идет, то писать бредятину про то, что DDD не указывает где логику хранить - нельзя. А идей всегда много разных высказывается, но в отличие от тебя я не хватаю первую понравившуюся идею, не возвожу ее в абсолют и не начинаю гнать пугру о том что правильно во всех случаях, а что нет. ООП у него оказывается приравнивается к говнокоду А мое личное мнение об анемике совпадает с Фаулеровской, в большинстве случаев анемику лепят т.к. просто отсутствует квалификация собрать правильный ООП
А повторять холивар 10-летней давности, и особенно с типами типа тебя, не знающими даже базовую теорию, предоставлю другим.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910497
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
17-77

так приведите конкретный пример хорошего использования DDD, только не пет проект, высосанный из пальца, а реально сложную предметную область, банки там, страхование или типа того, мне правда очень хочется посмотреть как использовать DDD, чтоб не наступить на тыщу граблей и чтоб сохранить солид и не делать god-объектов

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

а от сторонников я только и слышу - "не умеешь правильно готовить", ну так покажите как надо

у нас как раз банки, и ничего. Понятно что на практике всегда приходится идти на компромисы, но это не повод теперь выкинуть всю логику в сервисы и превратить ее в неподдерживаемую лапшу
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910498
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудух

у hVostt хотя бы есть несколько лет разработки проекта на CQRS + ES с нуля
а у вас что есть, кроме какашек для вентилятора?
Можно и повежливее в топики врываться, коли не обезьяна

он там на нуле и остался, от того, что обычно пишет этот чувак на форуме волосы дыбом встают, и этот топик хороший пример
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910523
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford
17-77

так приведите конкретный пример хорошего использования DDD, только не пет проект, высосанный из пальца, а реально сложную предметную область, банки там, страхование или типа того, мне правда очень хочется посмотреть как использовать DDD, чтоб не наступить на тыщу граблей и чтоб сохранить солид и не делать god-объектов

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

а от сторонников я только и слышу - "не умеешь правильно готовить", ну так покажите как надо

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

Кто-то там вам неподдерживаемой лапши понаписал, и вы теперь на форуме злобу вымещаете?
Очень на это смахивает.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910531
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot stenford#22052774
мда, у тебя отсутствуют совершенно базовые знания о разработке, уровни, про которые он говорит как раз и содержат в том числе доменные сущности, которые и обладают логикой (последняя цитата по ссылке там напрямую их упоминает), если-бы ты узнал об этой книжке не сегодня из этого топика, а хотя-бы слышал о ней в прошлом, то этого чудовищного бреда бы не нес, обычно даже джуны более подкованы в базовой теории, я честно говоря не разу не видел джуна, который обладал-бы насколько извращенным пониманием ООП
с уродцами типа тебя по другому нельзя, ты человеческого языка в принципе не понимаешь[/quot]

Практика показывает, что если юзер образован, то у него и с грамматикой и орфографией все в порядке.
Такой "резкий" "джуна" юзер, а так безграмотно пишет.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910604
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hexag0v
hVosttКонструктор использовать нельзя, так как во-первых, он не может быть асинхронным, во-вторых логика в конструкторе -- зло

Сложной логики с участием IO там быть не должно, в для простой асинхронность не нужна.

В конструкторе конечно логики быть не должно.
Но при создании агрегата сложная логика часто присутствует, асинхронность нужна, так как могут потребоваться данные из контекста.
Поэтому конструктор плохо подходит для создания агрегата. Создать экземпляр класса -- вот его задача.


Hexag0v
hVosttА что делать, если поддержать полностью валидный инвариант при изоляции на уровне агрегата нельзя?

Тут не понял.

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

По опыту таких сложных и даже где-то не очень логичных правил у бизнеса накапливается огромное количество. Абсолютно невозможно учесть всё это на уровне проектирования модели. Только если вы не создаёте ПО по ТЗ под ключ -- а так сейчас никто не разрабатывает.


Hexag0v
hVosttА что делать, если нам нужна операция, затрагивающая несколько агрегатов, в которой сложно чётко выделить явный корень агрегата операции?

А что будет если не совсем правильно выделить корень? Ничего страшного имхо, мелкий рефакторинг на край.

Речь не в правильности или неправильности. А в потере логики и смысла, что очень вредит и доменной модели, и единому языку. Кроме того, разработчика должно как можно меньше парить вопросы, где и как ему размещать логику. Признак хорошей архитектуры это сведение таких вопросов к минимуму.


Hexag0v
hVostt А что делать, когда подключили интеграцию с партнёром и он грузит такие заказы огромными пачками, десятки, сотни тысяч за раз, и партнёров много становится. И профилирование показывает жестойшее узкое место в этой команде?

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

Ну так вы и не ответили на вопрос.

-- А что, если у пациента горло болит?
-- Такое может с каждым произойти. Надо рассматривать каждый случай отдельно.

Понятно, что универсального решения нет. Но у Фаулеровского (от 2013 года) DDD никакого решения на этот счёт нет. Выкручивайтесь сами так сказать.


Hexag0v
hVosttНу а как же протестировать вот именно эту команду? Без учёта логики, инкапсулированной в домен (order.AddOrderItem)?

Тестировать отдельно класс Order, через метод GetTotal() например, в чем тут проблема?

В целом не вижу особых проблем с указанной командой.

Я не настаиваю, но я вижу здесь проблемы, так как лично с ними сталкивался в разработке промышленного ПО, очень крупного и дорогого. И цену этих проблем знаю не только я, но также и участники команд, с которыми работал, а также руководство.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910605
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hexag0v
hVostt
Хорошо бы иметь возможность выполнить серию команд в одной транзакции и получить полностью согласованный результат.


Не факт, что CQRS подходит для большого количества зависимых операций.

Фаулер писал на эту тему:
авторLike any pattern, CQRS is useful in some places, but not in others. Many systems do fit a CRUD mental model, and so should be done in that style.


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

Это очень удобная позиция, ну.. зависит от. Да, так оно и есть. Зависит. Но что делать новичкам? Откуда они знают что и от чего зависит? Как выбрать? Что делать?

Однако. Мы решили эту проблему, у нас и CRUD и сложная логика через CQRS прекрасно работают, плюс ещё EventSourcing, с которым тоже удалось решить множество проблем и вызовов.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910606
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
17-77
а от сторонников я только и слышу - "не умеешь правильно готовить", ну так покажите как надо


Это обычный способ уйти от ответа и объяснения.
Да, вы не умеете правильно готовить
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910607
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenford
А повторять холивар 10-летней давности, и особенно с типами типа тебя, не знающими даже базовую теорию, предоставлю другим.


Я пока не научился разговаривать со свиньями.
Когда начнёшь разговаривать как приличный и разумный человек, пиши.
Обижаться на тебя не буду, это грешно.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910646
91145
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
17-77
а от сторонников я только и слышу - "не умеешь правильно готовить", ну так покажите как надо


Это обычный способ уйти от ответа и объяснения.
Да, вы не умеете правильно готовить

Давайте тогда так )

Проект, код из которого вы показали
Пример cqrs

На Ваш взгляд , насколько удачно там применен cqrs?
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910652
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
91145
Проект, код из которого вы показали
Пример cqrs

а что в C# означает такая запись:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
public class CreateOrderCommand
{
    [DataMember] // это название какого-то блока данных?
    public string UserId {get; private set;} // а это относится к C# или уже к CQRS?

    [DataMember] // и опять он?
    public string UserName {get; private set;}
};
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910682
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
91145
Давайте тогда так )

Проект, код из которого вы показали
Пример cqrs

На Ваш взгляд , насколько удачно там применен cqrs?


С точки зрения учебного примера -- довольно хорошо, легко находится то, что есть в теории.
Хорошо понятен и виден принцип, и даже полноценная его реализация. Потому как обычно отсутствие хоть какой-либо вменяемой готовой реализации к теории является серьёзной проблемой для новичков.

С практической же точки зрения -- плохо.
Когда мы хотим применить CQRS, мы это делаем, чтобы получить определённую выгоду, профит.
А не получить медальку и одобрительное похлопывание по плечу от гуру или евангелиста методики.

Здесь профита достигается мало.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910683
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудух
а что в C# означает такая запись:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
public class CreateOrderCommand
{
    [DataMember] // это название какого-то блока данных?
    public string UserId {get; private set;} // а это относится к C# или уже к CQRS?

    [DataMember] // и опять он?
    public string UserName {get; private set;}
};



Это атрибут для сериализации команд. Так как команды являются, и должны являться, чистыми POCO/DTO, возникает закономерное желание их куда-то сохранить. Ещё можно их направлять в единую точку обработки или в диспетчер через какую-нибудь шину команд, таким образом получить возможность более гибкого масштабирования.
...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910684
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а вот это почему так объявляется (get/set)? и как именно используется в CQRS?
полудух
Код: c#
1.
public string UserId {get; private set;}

...
Рейтинг: 0 / 0
DDD разнесение кода логики по классам
    #39910685
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt
Здесь профита достигается мало.

т.е. пример - говно?
...
Рейтинг: 0 / 0
25 сообщений из 169, страница 2 из 7
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / DDD разнесение кода логики по классам
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]