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

Domain driven design 如何组织领域驱动的设计项目?,domain-driven-design,organization,Domain Driven Design,Organization,我已经开始学习DDD,想知道其他人是如何组织他们的项目的 我从组织我的聚合开始: MyApp.Domain(域模型的名称空间) MyApp.Domain.Product -产品 -IPProductService -IPProductRepository -等 MyApp.Domain.Comment -评论 -ICommentService -ICommentRepository -etc MyApp.Infrastructure -… MyApp.Repositories -ProductR

我已经开始学习DDD,想知道其他人是如何组织他们的项目的

我从组织我的聚合开始:

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

MyApp.Domain.Product
-产品
-IPProductService
-IPProductRepository
-等

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

MyApp.Infrastructure
-…

MyApp.Repositories
-ProductRepository:IPProductRepository
-etc

我遇到的问题是,我必须将我的域产品引用为MyApp.domain.product.product或product.product。我还与产品的linq数据模型发生冲突……我必须使用难看的代码行来区分这两个模型,例如MyApp.Domain.product.product和MyApp.Respoitories.product

我真的很想看看其他人是如何组织他们的DDD解决方案的

我正在使用VisualStudio作为我的IDE


非常感谢。

只要有可能,我都会尽量让事情变得简单,所以通常这样的事情对我来说很有用:

域-所有特定于域的类都共享此命名空间

数据-从域中抽象数据库的薄层

应用程序-所有“支持代码”、日志、共享实用程序代码、服务使用者等

Web-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将是一个聚合根,因为当它实例化时,它可能包含其他对象,例如客户对象和订单行集合,并且您只能通过订单对象访问该特定订单的订单行

但是,为了保持简单,我不会有一个“master”对象,它只包含其他所有内容,没有其他用途,因此order类本身将具有在应用程序中有用的值和属性

因此,我将参考以下内容:

Myapp.Domain.Sales.Order.TotalCost

Myapp.Domain.Sales.Order.OrderDate

Myapp.Domain.Sales.Order.Customer.PreferredInvoiceMethod

Myapp.Domain.Sales.Order.Customer.Address.Zip


等等。

您的域可能有 名字,所以你应该用这个 名称作为名称空间

我通常把它放在存储库中 实施和数据访问 名为 域下的持久性 命名空间

应用程序使用自己的名称
作为命名空间。

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

Acme.Core.dll
[根命名空间:
Acme
]

这清楚地表明,域在应用程序的所有其他部分的范围内。(更多信息,请参见杰弗里·巴勒莫)

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

Acme.Data.dll
[根命名空间:
Acme.Data
]

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

Acme.Presentation.dll
[根命名空间:
Acme.Presentation
]

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


Acme.Web
[根命名空间:
Acme.Web
]

我想检查codecamp服务器,因为那里的设置非常常见

他们有一个核心项目,其中包括应用程序层和域层。即洋葱的内部()

实际上,我喜欢将核心分解成单独的项目来控制依赖的方向。因此,我通常:


MyNamespace.SomethingWeb虽然您也是一名.Net开发人员,但Eric Evans和Citerus提供的DDD是一个很好的资源

在doc的代码中,您可以看到DDD组织进入有界上下文并聚合在一起,就在Java包中

另外,你可以考虑Billy McCafferty的。这是一个ASP.NETMVC、NHibernate/Fluent NHibernate实现,它是在考虑DDD的情况下构建的

诚然,您仍然需要应用文件夹/名称