Определение прикладных уровней в Domain-Driven-Design - PullRequest
5 голосов
/ 16 апреля 2010

У меня вопрос по поводу DDD. Я создаю приложение для изучения DDD, и у меня есть вопрос о наслоении. У меня есть приложение, которое работает так:

вызовы уровня пользовательского интерфейса => Уровень приложения -> Доменный уровень -> База данных

Вот небольшой пример того, как выглядит код:

//****************UI LAYER************************
//Uses Ioc to get the service from the factory.
//This factory would be in the MyApp.Infrastructure.dll
IImplementationFactory factory = new ImplementationFactory();

//Interface and implementation for Shopping Cart service would be in MyApp.ApplicationLayer.dll
    IShoppingCartService service = factory.GetImplementationFactory<IShoppingCartService>();

    //This is the UI layer,
    //Calling into Application Layer
    //to get the shopping cart for a user.

    //Interface for IShoppingCart would be in MyApp.ApplicationLayer.dll
    //and implementation for IShoppingCart would be in MyApp.Model.
    IShoppingCart shoppingCart = service.GetShoppingCartByUserName(userName);

    //Show shopping cart information.
    //For example, items bought, price, taxes..etc
    ...

    //Pressed Purchase button, so even for when
    //button is pressed.
    //Uses Ioc to get the service from the factory again.
    IImplementationFactory factory = new ImplementationFactory();
    IShoppingCartService service = factory.GetImplementationFactory<IShoppingCartService>();
    service.Purchase(shoppingCart);


    //**********************Application Layer**********************
    public class ShoppingCartService : IShoppingCartService
    {
       public IShoppingCart GetShoppingCartByUserName(string userName)
       {
           //Uses Ioc to get the service from the factory.
           //This factory would be in the MyApp.Infrastructure.dll
           IImplementationFactory factory = new ImplementationFactory();

           //Interface for repository would be in MyApp.Infrastructure.dll
           //but implementation would by in MyApp.Model.dll
           IShoppingCartRepository repository = factory.GetImplementationFactory<IShoppingCartRepository>();

           IShoppingCart shoppingCart = repository.GetShoppingCartByUserName(username);
           //Do shopping cart logic like calculating taxes and stuff
           //I would put these in services but not sure?
           ...

           return shoppingCart;
       }

       public void Purchase(IShoppingCart shoppingCart)
       {
            //Do Purchase logic and calling out to repository
            ...
       }
    }

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

Спасибо!

Ответы [ 4 ]

3 голосов
/ 16 апреля 2010

Когда вы спрашиваете

Должны ли мои модели выходить из модели моего домена?

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

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

Что касается

IShoppingCart shoppingCart = repository.GetShoppingCartByUserName(username);
//Do shopping cart logic like calculating taxes and stuff
//I would put these in services but not sure?

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

2 голосов
/ 16 апреля 2010

DDD работает лучше всего, когда службы (прикладной уровень) предоставляют только команды для объектов домена, а не сами объекты.

В вашем примере я бы создал сервисный метод, такой как Покупка (strng productName, int кол-во), который внутренне получить ShoppingCart из репозитория (здесь не нужно использовать интерфейс) получить товар (по его названию) из репозитория и позвоните в корзину. Добавить товар (товар, количество)

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

1 голос
/ 16 апреля 2010

У вас должен быть один тонкий слой между объектами домена и сервисами для манипулирования объектами домена (рекомендуется Эриком Эвансом). Это имя объекта обычно заканчивается на «Менеджер». Например PurchaseManager или аналогичный. Вся логика, связывающая разные доменные объекты (пользователь, покупка, адрес…), находится в этом объекте.

  • Диспетчер сервисных вызовов. GetSomething ()
  • Менеджер получает данные из разных репозиториев, выполняет бизнес-логику и возвращает результат
  • Manger Return Result, но сам по себе никогда не вернет доменные объекты! Если у вас есть объект домена с именем User, вы должны придерживаться соглашения об именовании, которое вы придумали, и сопоставить User с UserDataContract или аналогичным. Не выставляйте доменные объекты. Это дополнительная работа, но вы не должны связывать свою модель домена с пользовательским интерфейсом.
  • Во многих случаях объект домена имеет методы для выполнения бизнес-логики
0 голосов
/ 05 октября 2016

По вашему вопросу:

«Кажется, я положил большинство своих бизнес-правил в сервисы, а не в модели, и я не уверен, что это правильно? "

Если бизнес-правило не имеет доступа к другим ресурсам (базе данных, службам, объектам домена), вы можете иметь правило в самом объекте домена. Если он имеет доступ к другим ресурсам, вам следует поместить их в доменные службы.

...