如何组织领域驱动的设计项目?

时间:2009-02-09 15:22:52

标签: domain-driven-design organization

我开始学习DDD并想知道其他人如何组织他们的项目。

我开始组织我的AggregateRoots:

MyApp.Domain(域模型的命名空间)

MyApp.Domain.Product
- 产品
- IProductService
- IProductRepository
- 等

MyApp.Domain.Comment
- 评论
- ICommentService
- ICommentRepository
- 等

MyApp.Infrastructure
- ......

MyApp.Repositories
- ProductRepository:IProductRepository
- 等

我遇到的问题是我必须将我的域名产品称为MyApp.Domain.Product.Product或Product.Product。我也与产品的linq数据模型发生冲突....我必须使用丑陋的代码行来解析两者之间的问题,例如MyApp.Domain.Product.Product和MyApp.Respoitories.Product。

我真的很想知道其他人如何组织他们的DDD解决方案......

我使用Visual Studio作为我的IDE。

非常感谢。

5 个答案:

答案 0 :(得分:20)

我尽量保持简单,所以通常这样的事情对我有用:

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

我试图记住的想法是,“域”命名空间是捕获应用程序的实际逻辑的原因。那么你可以与“领域专家”(将使用该应用程序的家伙)谈论的内容是什么。 如果我因为他们提到的东西而编码某些东西,它应该在域命名空间中,并且每当我编写他们未提及的东西(如日志记录,跟踪错误等)时,它不应该在域命名空间中。

因此我对制作过于复杂的对象层次结构也很谨慎。理想情况下,非编码人员应该直观地理解域模型的简化图。

为此,我通常不会通过详细考虑模式开始。我尝试按照标准的面向对象设计指南,尽可能简单地对域进行建模。什么需要成为一个对象?它们有什么关系?

在我看来,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

答案 1 :(得分:5)

我喜欢在应用程序的根命名空间中拥有域,在自己的程序集中:

Acme.Core.dll [root namespace:Acme]

这巧妙地表示域名在应用程序的所有其他部分的范围内。 (有关更多信息,请参阅Jeffrey Palermo撰写的The Onion Architecture)。

接下来,我有一个数据程序集(通常带有NHibernate),它将域对象映射到数据库。该层实现了存储库和服务接口:

Acme.Data.dll [root namespace:Acme.Data]

然后,我有一个演示程序集,声明我的UI模式选择元素:

Acme.Presentation.dll [root namespace:Acme.Presentation]

最后,还有UI项目(假设这里有一个Web应用程序)。这是前面层中元素的组成发生的地方:

Acme.Web [root namespace:Acme.Web]

答案 2 :(得分:3)

虽然您也是.Net开发人员,但Eric Evans和Citerus的DDD Java implementation reference of the cargo app是一个很好的资源。

在doc'd代码中,您可以在Java包中看到DDD组织进入有界上下文和聚合操作。

此外,您可能会考虑Billy McCafferty的Sharp Architecture。这是一个ASP.Net MVC,NHibernate / Fluent NHibernate实现,它考虑了DDD。

不可否认,您仍需要应用文件夹/命名空间解决方案来提供上下文。但是,将埃文斯的方法与#Arch结合起来,你就应该顺利了。

告诉我们您的目标。我也走在同一条路上,离你不远!

快乐编码,

Kurt Johnson

答案 3 :(得分:0)

您的域名可能有 名称,所以你应该使用它 命名为命名空间。

我通常放置存储库 实施和数据访问 名称空间中的详细信息 在域名下坚持不懈 命名空间。

应用程序使用自己的名称 as namespace。

答案 4 :(得分:0)

我会检查codecampserver,因为那里的设置很常见。

他们有一个核心项目,其中包括应用程序和域层。即洋葱的内部(http://jeffreypalermo.com/blog/the-onion-architecture-part-1/)。

我实际上喜欢将核心拆分为单独的项目来控制依赖的方向。通常我有:

MyNamespace.SomethingWeb< - 多个UI MyNamespace.ExtranetWeb< - 多个UI

MyNamespace.Application< - Evans的应用程序层,其类包含CustomerService
MyNamespace.Domain

  • MyNamespace.Domain.Model< - entities
  • MyNamespace.Domain.Services< - doman services
  • MyNamespace.Domain.Repositories

MyNamespace.Infrastructure< - repo implementation etc.

MyNamespace.Common< - 所有其他项目都依赖于Logger,Util类等的项目。