Я стараюсь сделать все очень просто, когда могу, поэтому обычно что-то вроде этого работает для меня:
Myapp.Domain - все доменные классы совместно используют это пространство имен
Myapp.Data - Тонкий слой, который абстрагирует базу данных от домена.
Myapp.Application - все «коды поддержки», ведение журнала, общий код утилит, потребители услуг и т. Д.
Myapp.Web - веб-интерфейс
Таким образом, классы будут, например:
- Myapp.Domain.Sales.Order
- Myapp.Domain.Sales.Customer
- Myapp.Domain.Pricelist
- Myapp.Data.OrderManager
- Myapp.Data.CustomerManager
- Myapp.Application.Utils
- Myapp.Application.CacheTools
1029 * Etc. *
Идея, которую я пытаюсь запомнить, заключается в том, что пространство имен «домен» - это то, что отражает реальную логику приложения. Итак, о чем вы можете поговорить с «экспертами в области» (парнями, которые будут использовать приложение).
Если я кодирую что-то из-за того, что они упомянули, это должно быть в пространстве имен домена, и всякий раз, когда я кодирую что-то, чего они не упомянули (например, ведение журнала, отслеживание ошибок и т. Д.), Это НЕ должно быть в пространстве имен домена.
Из-за этого я также опасаюсь создавать слишком сложные иерархии объектов. В идеале несколько упрощенный рисунок модели предметной области должен быть интуитивно понятен некодерам.
С этой целью я обычно не начинаю с размышления о паттернах во всех деталях. Я пытаюсь смоделировать домен настолько просто, насколько могу, просто следуя стандартным руководствам объектно-ориентированного проектирования. Каким должен быть объект? Как они связаны?
DDD, на мой взгляд, касается работы со сложным программным обеспечением, но если ваше программное обеспечение само по себе не очень сложное, вы можете легко оказаться в ситуации, когда DDD делает вещи, усложняя, а не убирая их.
Когда у вас будет определенный уровень сложности в вашей модели, вы начнете видеть, как определенные вещи должны быть организованы, а затем вы узнаете, какие шаблоны использовать, какие классы являются агрегатами и т. Д.
В моем примере Myapp.Domain.Sales.Order будет агрегатным корнем в том смысле, что при его создании он, скорее всего, будет содержать другие объекты, такие как объект клиента и набор строк заказа, и вы будете иметь доступ только к строки заказа для этого конкретного заказа через объект заказа.
Однако, чтобы все было просто, у меня не было бы «главного» объекта, который бы содержал только все остальное и не имел других целей, поэтому сам класс заказа будет иметь значения и свойства, которые полезны в приложении.
Так что я буду ссылаться на такие вещи, как:
Myapp.Domain.Sales.Order.TotalCost
Myapp.Domain.Sales.Order.OrderDate
Myapp.Domain.Sales.Order.Customer.PreferredInvoiceMethod
Myapp.Domain.Sales.Order.Customer.Address.Zip
и т.д.