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

发布于 2024-07-13 13:17:16 字数 738 浏览 11 评论 0原文

我已经开始学习 DDD,并想了解其他人如何组织他们的项目。

我首先围绕我的 AggregateRoots 进行组织:

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

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

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

MyApp.Infrastructure
- ...

MyApp.Repositories
- 产品存储库:IProductRepository
- 等等

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

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

我使用 Visual Studio 作为我的 IDE。

多谢。

I've started learning about DDD and wanted to know how others have organised their projects.

I've started off by organising around my AggregateRoots:

MyApp.Domain (namespace for domain model)

MyApp.Domain.Product
- Product
- IProductService
- IProductRepository
- etc

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

MyApp.Infrastructure
- ...

MyApp.Repositories
- ProductRepository : IProductRepository
- etc

The problem i've bumped into with this is that i have to reference my domain product as MyApp.Domain.Product.Product or Product.Product. I also get a conflict with my linq data model for product....I have to use ugly lines of code to distiguish between the two such as MyApp.Domain.Product.Product and MyApp.Respoitories.Product.

I am really interested to see how others have organised their solutions for DDD...

I am using Visual Studio as my IDE.

Thanks alot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

她如夕阳 2024-07-20 13:17:16

我尽量让事情变得非常简单,所以通常这样的事情对我有用:

Myapp.Domain - 所有特定于域的类共享这个命名空间

Myapp.Data - 从域中抽象数据库的薄层。

Myapp.Application - 所有“支持代码”、日志记录、共享实用程序代码、服务消费者等

Myapp.Web - Web UI

因此类将是例如:

  • 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

等。

I try to keep things very simple whenever I can, so usually something like this works for me:

Myapp.Domain - All domain specific classes share this namespace

Myapp.Data - Thin layer that abstracts the database from the domain.

Myapp.Application - All "support code", logging, shared utility code, service consumers etc

Myapp.Web - The web UI

So classes will be for example:

  • Myapp.Domain.Sales.Order
  • Myapp.Domain.Sales.Customer
  • Myapp.Domain.Pricelist
  • Myapp.Data.OrderManager
  • Myapp.Data.CustomerManager
  • Myapp.Application.Utils
  • Myapp.Application.CacheTools

Etc.

The idea I try to keep in mind as I go along is that the "domain" namespace is what captures the actual logic of the application. So what goes there is what you can talk to the "domain experts" (The dudes who will be using the application) about.
If I am coding something because of something that they have mentioned, it should be in the domain namespace, and whenever I code something that they have not mentioned (like logging, tracing errors etc) it should NOT be in the domain namespace.

Because of this I am also wary about making too complicated object hierarchies. Ideally a somewhat simplified drawing of the domain model should be intuitively understandable by non-coders.

To this end I don't normally start out by thinking about patterns in much detail. I try to model the domain as simple as I can get away with, following just standard object-oriented design guidelines. What needs to be an object? How are they related?

DDD in my mind is about handling complex software, but if your software is not itself very complex to begin with you could easily end up in a situation where the DDD way of doing things adds complexity rather than removes it.

Once you have a certain level of complexity in your model you will start to see how certain things should be organised, and then you will know which patterns to use, which classes are aggregates etc.

In my example, Myapp.Domain.Sales.Order would be an aggregate root in the sense that when it is instanced it will likely contain other objects, such as a customer object and collection of order lines, and you would only access the order lines for that particular order through the order object.

However, in order to keep things simple, I would not have a "master" object that only contains everything else and has no other purpose, so the order class will itself have values and properties that are useful in the application.

So I will reference things like:

Myapp.Domain.Sales.Order.TotalCost

Myapp.Domain.Sales.Order.OrderDate

Myapp.Domain.Sales.Order.Customer.PreferredInvoiceMethod

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

etc.

月寒剑心 2024-07-20 13:17:16

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

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

这清楚地表明了这样一个事实:域在应用程序的所有其他部分的范围内。 (有关更多信息,请参阅 Jeffrey Palermo 的洋葱架构)。

接下来,我有一个将域对象映射到数据库的数据组件(通常使用 NHibernate)。 该层实现存储库和服务接口:

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

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

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

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

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

I like having the domain in the root namespace of the application, in its own assembly:

Acme.Core.dll [root namespace: Acme]

This neatly represents the fact that the domain is in scope of all other portions of the application. (For more, see The Onion Architecture by Jeffrey Palermo).

Next, I have a data assembly (usually with NHibernate) that maps the domain objects to the database. This layer implements repository and service interfaces:

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

Then, I have a presentation assembly declaring elements of my UI-pattern-of-choice:

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

Finally, there is the UI project (assuming a web app here). This is where the composition of the elements in preceding layers takes place:

Acme.Web [root namespace: Acme.Web]

︶葆Ⅱㄣ 2024-07-20 13:17:16

尽管您也是一名 .Net 开发人员,但来自 DDD 的 Cargo 应用程序的 Java 实现参考作者:Eric Evans 和 Citerus 是一个很好的资源。

在文档代码中,您可以在 Java 包中看到 DDD 组织到有界上下文中并进行聚合。

此外,您还可以考虑 Billy McCafferty 的 Sharp 架构。 它是一个 ASP.Net MVC、NHibernate/Fluent NHibernate 实现,在构建时考虑了 DDD。

诚然,您仍然需要应用文件夹/命名空间解决方案来提供上下文。 但是,将 Evans 方法与 #Arch 结合起来,您应该就可以顺利进行了。

让我们知道您要做什么。 我也在同一条路上,离你不远!

快乐编码,

库尔特·约翰逊

Although you're also a .Net developer, the Java implementation reference of the cargo app from DDD by Eric Evans and Citerus is a good resource.

In the doc'd code, you can see the DDD-organization into bounded contexts and aggregates in action, right in the Java packages.

Additionally, you might consider Billy McCafferty's Sharp Architecture. It's an ASP.Net MVC, NHibernate/Fluent NHibernate implementation that is built with DDD in mind.

Admittedly, you will still need to apply a folder/namespace solution to provide the contexts. But, couple the Evans approach with #Arch and you should be well on your way.

Let us know what you are going with. I am on the same path as well, and not far from you!

Happy coding,

Kurt Johnson

黎歌 2024-07-20 13:17:16

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

我通常把存储库
实施和数据访问
名称空间中的详细信息
域下持久化
命名空间。

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

Your domain probably have a
name, so you should use this
name as namespace.

I usally put repository
implementation and data access
details in a namespace called
Persistance under the domain
namespace.

The application use its own name
as namespace.

孤独患者 2024-07-20 13:17:16

我会检查 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 <-- 实体
  • MyNamespace.Domain.Services <-- 域服务
  • MyNamespace.Domain.Repositories

MyNamespace.Infrastruct <-- 存储库实现等

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

I'd check out codecampserver since the setup there is quite common.

They have a core project in which they include both the application and domain layers. I.e. the insides of the onion (http://jeffreypalermo.com/blog/the-onion-architecture-part-1/).

I actually like to break the core apart into separate projects to control the direction of dependency. So typically I have:

MyNamespace.SomethingWeb <-- multiple UIs
MyNamespace.ExtranetWeb <-- multiple UIs

MyNamespace.Application <-- Evans' application layer with classes like CustomerService
MyNamespace.Domain

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

MyNamespace.Infrastructure <-- repo implementation etc.

MyNamespace.Common <-- A project which all other projects have a dependency to which has things like a Logger, Util classes, etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文