在域驱动设计中,您可以在UI中使用域实体吗?

时间:2022-08-31 12:40:57

In many leading DDD projects, especially MVC style, I see the UI using display objects that mirror domain entities, rather than using those domain objects directly. This style is obviously for decoupling and separation of concerns, and I personally prefer this style.

在许多领先的DDD项目中,特别是MVC样式,我看到UI使用镜像域实体的显示对象,而不是直接使用这些域对象。这种风格显然是为了解决和分离问题,我个人更喜欢这种风格。

But what I'm not sure of, is whether this a strict tenet of DDD, or whether this is more just different developers' interpretation of it.

但我不确定的是,这是否是DDD的严格原则,还是这不仅仅是开发人员对它的不同解释。

Can you use your domain objects directly in the UI, and still be following the DDD methodology in that act?

您是否可以直接在UI中使用域对象,并且仍然遵循该行为中的DDD方法?

Or is it a DDD best practice to always use display objects?

或者,总是使用显示对象是DDD最佳实践吗?

Note: While I mention MVC, I'm really interested in whether display objects must be used in almost all DDD compatible UI patterns in a DDD project.

注意:虽然我提到了MVC,但我真的很感兴趣是否必须在DDD项目中的几乎所有DDD兼容的UI模式中使用显示对象。

6 个解决方案

#1


DDD is a way of thinking while designing a software that starts with modelling the domain. As the webpage puts it:

在设计从域建模开始的软件时,DDD是一种思考方式。正如网页所说:

Domain-driven design is not a technology or a methodology. It is a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains.

域驱动设计不是技术或方法。这是一种思维方式和一系列优先事项,旨在加速必须处理复杂领域的软件项目。

One thing that follows naturally out of this design pattern is a layered architecture. As it is said in DDD Pattern Summaries

从这种设计模式中自然而然的一件事是分层架构。正如在DDD模式摘要中所说的那样

Partition a complex program into LAYERS. Develop a design within each LAYER that is cohesive and that depends only on the layers below. Follow standard architectural patterns to provide loose coupling to the layers above. Concentrate all the code related to the domain model in one layer and isolate it from the user interface, application, and infrastructure code. The domain objects, free of the responsibility of displaying themselves, storing themselves, managing application tasks, and so forth, can be focused on expressing the domain model. This allows a model to evolve to be rich enough and clear enough to capture essential business knowledge and put it to work.

将复杂程序划分为LAYERS。在每个LAYER中开发一个具有凝聚力的设计,并且仅取决于下面的层。遵循标准的架构模式,为上面的层提供松散的耦合。将所有与域模型相关的代码集中在一个层中,并将其与用户界面,应用程序和基础架构代码隔离开来。域对象无需显示自身,存储自身,管理应用程序任务等,可以专注于表达域模型。这使得模型能够发展到足够丰富和清晰,以捕获必要的业务知识并使其发挥作用。

Whether you need to have display objects to do that? That is just one way of implementing this, but might not even be the best to provide loose coupling. As for an example: maybe the view layer is but a webbrowser and xlt files to visualize xml files emmitted by the business layer? If anybody has more fitting examples, please add them. My point is that DDD stresses a layered architecture, but does not limit this to one possible solution.

是否需要显示对象才能这样做?这只是实现这一点的一种方式,但可能甚至不是提供松散耦合的最佳方法。举个例子:也许视图层只是一个webbrowser和xlt文件来可视化业务层提取的xml文件?如果有人有更合适的例子,请添加它们。我的观点是DDD强调分层架构,但不限于此可能的解决方案。

#2


If you're doing an MVC pattern, you need view objects; the DDD is just your model. That doesn't mean you must always use MVC; a DDD could be built, say, as a simulator, where all you look at is log messages emitted. But in MVC you really should have separate view objects.

如果你正在做一个MVC模式,你需要查看对象; DDD只是你的模特。这并不意味着你必须始终使用MVC;例如,可以构建DDD作为模拟器,您所看到的就是发出的日志消息。但是在MVC中你真的应该有单独的视图对象。

Now, ask yourself why that would be? The answer is that the view can change, even though the business model doesn't. The DDD model should express, in the business's terms, what is essential to the business.

现在,问问自己为什么会这样?答案是视图可以改变,即使业务模型没有。 DDD模型应该以业务的术语表达对业务至关重要的内容。

#3


I didn't really start to understand why or how you would decouple the domain model from presentation concerns until I started following the work of Greg Young and Udi Dahan (via Martin Fowler).

在我开始关注Greg Young和Udi Dahan(通过Martin Fowler)的工作之前,我并没有真正开始理解为什么或如何将领域模型与演示问题分离。

They have been teaching a principle known as Command and Query Responsibility Segregation (CQRS).

他们一直在教导一种称为命令和查询责任隔离(CQRS)的原则。

My interpretation of CQRS is that there are two sets of responsibilities that can pull a domain model in different directions, resulting in a model that does a mediocre job of both. The two responsibilities are commands (i.e. behavior that would cause a write to the database) and queries (i.e. reading from the database in order to fetch data for UI consumption). An example would be adding getters and setters to your entities to support databinding in the UI. If your model has getters and setters, it will probably do a poor job of modeling state changes that need to happen transactionally or encapsulating business logic. It will also have no way of modeling the business context of state changes (see Event Sourcing).

我对CQRS的解释是,有两组责任可以将领域模型拉向不同的方向,从而形成一个两者平庸的模型。这两个职责是命令(即将导致写入数据库的行为)和查询(即从数据库读取以获取用于UI消费的数据)。一个示例是向实体添加getter和setter以支持UI中的数据绑定。如果您的模型具有getter和setter,那么在建模需要在事务上发生的状态更改或封装业务逻辑时,它可能会做得很差。它也无法对状态变化的业务环境建模(参见事件采购)。

In DDD terms, you might say that the domain model and the presentation model are usually in separate Bounded Contexts.

在DDD术语中,您可能会说域模型和表示模型通常位于单独的有界上下文中。

The solution as prescribed by CQRS is to create one model for commands and another for queries. If your current model has methods for changing state (i.e. the behavior in the model), and getters that expose state to a UI for databinding, you would refactor these two responsibilities into separate models for commands and queries. The query model will not be mapped to your domain entities, but instead directly to the database. If your database doesn't capture derived state from your domain model, check out a pattern called Eager Read Derivation.

CQRS规定的解决方案是为命令创建一个模型,为查询创建另一个模型。如果您当前的模型具有更改状态的方法(即模型中的行为),以及将状态公开给UI以进行数据绑定的getter,您可以将这两个职责重构为命令和查询的单独模型。查询模型不会映射到您的域实体,而是直接映射到数据库。如果您的数据库未捕获域模型的派生状态,请查看名为Eager Read Derivation的模式。

If your system is simply CRUD and has no behavior, try out a scaffolding system that can be automatically built off of your database schema, like ASP.NET Dynamic Data

如果您的系统只是CRUD且没有任何行为,请尝试一个可以自动构建数据库模式的脚手架系统,如ASP.NET动态数据

#4


Within an MVC design you would typically have a mapping from Repository -> Domain Models and then from Domain Models -> View Models. The View Models often contain Domain Objects though.

在MVC设计中,您通常会从Repository - > Domain Models,然后从Domain Models - > View Models获得映射。视图模型通常包含域对象。

#5


The answer is quite straight :

答案很简单:

  • The domain objects have domain oriented design and methods.
  • 域对象具有面向领域的设计和方法。

  • The view objects have view/control oriented design and methods.
  • 视图对象具有面向视图/控件的设计和方法。

If you can use your domain objects in the view, they are maybe not quite domain oriented.

如果您可以在视图中使用域对象,则它们可能不是面向域的。

#6


Domain objects are really the internal logic inside your business logic layer. They shouldn't be directly exposed to your clients (UI layer). Instead, encapsulate the usage of your domain model into application services. The application services can utilize lightweight DTOs and/or command objects to pass data and intent between the client and the domain model.

域对象实际上是业务逻辑层中的内部逻辑。它们不应直接暴露给您的客户(UI层)。相反,将域模型的使用封装到应用程序服务中。应用程序服务可以利用轻量级DTO和/或命令对象在客户端和域模型之间传递数据和意图。

#1


DDD is a way of thinking while designing a software that starts with modelling the domain. As the webpage puts it:

在设计从域建模开始的软件时,DDD是一种思考方式。正如网页所说:

Domain-driven design is not a technology or a methodology. It is a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains.

域驱动设计不是技术或方法。这是一种思维方式和一系列优先事项,旨在加速必须处理复杂领域的软件项目。

One thing that follows naturally out of this design pattern is a layered architecture. As it is said in DDD Pattern Summaries

从这种设计模式中自然而然的一件事是分层架构。正如在DDD模式摘要中所说的那样

Partition a complex program into LAYERS. Develop a design within each LAYER that is cohesive and that depends only on the layers below. Follow standard architectural patterns to provide loose coupling to the layers above. Concentrate all the code related to the domain model in one layer and isolate it from the user interface, application, and infrastructure code. The domain objects, free of the responsibility of displaying themselves, storing themselves, managing application tasks, and so forth, can be focused on expressing the domain model. This allows a model to evolve to be rich enough and clear enough to capture essential business knowledge and put it to work.

将复杂程序划分为LAYERS。在每个LAYER中开发一个具有凝聚力的设计,并且仅取决于下面的层。遵循标准的架构模式,为上面的层提供松散的耦合。将所有与域模型相关的代码集中在一个层中,并将其与用户界面,应用程序和基础架构代码隔离开来。域对象无需显示自身,存储自身,管理应用程序任务等,可以专注于表达域模型。这使得模型能够发展到足够丰富和清晰,以捕获必要的业务知识并使其发挥作用。

Whether you need to have display objects to do that? That is just one way of implementing this, but might not even be the best to provide loose coupling. As for an example: maybe the view layer is but a webbrowser and xlt files to visualize xml files emmitted by the business layer? If anybody has more fitting examples, please add them. My point is that DDD stresses a layered architecture, but does not limit this to one possible solution.

是否需要显示对象才能这样做?这只是实现这一点的一种方式,但可能甚至不是提供松散耦合的最佳方法。举个例子:也许视图层只是一个webbrowser和xlt文件来可视化业务层提取的xml文件?如果有人有更合适的例子,请添加它们。我的观点是DDD强调分层架构,但不限于此可能的解决方案。

#2


If you're doing an MVC pattern, you need view objects; the DDD is just your model. That doesn't mean you must always use MVC; a DDD could be built, say, as a simulator, where all you look at is log messages emitted. But in MVC you really should have separate view objects.

如果你正在做一个MVC模式,你需要查看对象; DDD只是你的模特。这并不意味着你必须始终使用MVC;例如,可以构建DDD作为模拟器,您所看到的就是发出的日志消息。但是在MVC中你真的应该有单独的视图对象。

Now, ask yourself why that would be? The answer is that the view can change, even though the business model doesn't. The DDD model should express, in the business's terms, what is essential to the business.

现在,问问自己为什么会这样?答案是视图可以改变,即使业务模型没有。 DDD模型应该以业务的术语表达对业务至关重要的内容。

#3


I didn't really start to understand why or how you would decouple the domain model from presentation concerns until I started following the work of Greg Young and Udi Dahan (via Martin Fowler).

在我开始关注Greg Young和Udi Dahan(通过Martin Fowler)的工作之前,我并没有真正开始理解为什么或如何将领域模型与演示问题分离。

They have been teaching a principle known as Command and Query Responsibility Segregation (CQRS).

他们一直在教导一种称为命令和查询责任隔离(CQRS)的原则。

My interpretation of CQRS is that there are two sets of responsibilities that can pull a domain model in different directions, resulting in a model that does a mediocre job of both. The two responsibilities are commands (i.e. behavior that would cause a write to the database) and queries (i.e. reading from the database in order to fetch data for UI consumption). An example would be adding getters and setters to your entities to support databinding in the UI. If your model has getters and setters, it will probably do a poor job of modeling state changes that need to happen transactionally or encapsulating business logic. It will also have no way of modeling the business context of state changes (see Event Sourcing).

我对CQRS的解释是,有两组责任可以将领域模型拉向不同的方向,从而形成一个两者平庸的模型。这两个职责是命令(即将导致写入数据库的行为)和查询(即从数据库读取以获取用于UI消费的数据)。一个示例是向实体添加getter和setter以支持UI中的数据绑定。如果您的模型具有getter和setter,那么在建模需要在事务上发生的状态更改或封装业务逻辑时,它可能会做得很差。它也无法对状态变化的业务环境建模(参见事件采购)。

In DDD terms, you might say that the domain model and the presentation model are usually in separate Bounded Contexts.

在DDD术语中,您可能会说域模型和表示模型通常位于单独的有界上下文中。

The solution as prescribed by CQRS is to create one model for commands and another for queries. If your current model has methods for changing state (i.e. the behavior in the model), and getters that expose state to a UI for databinding, you would refactor these two responsibilities into separate models for commands and queries. The query model will not be mapped to your domain entities, but instead directly to the database. If your database doesn't capture derived state from your domain model, check out a pattern called Eager Read Derivation.

CQRS规定的解决方案是为命令创建一个模型,为查询创建另一个模型。如果您当前的模型具有更改状态的方法(即模型中的行为),以及将状态公开给UI以进行数据绑定的getter,您可以将这两个职责重构为命令和查询的单独模型。查询模型不会映射到您的域实体,而是直接映射到数据库。如果您的数据库未捕获域模型的派生状态,请查看名为Eager Read Derivation的模式。

If your system is simply CRUD and has no behavior, try out a scaffolding system that can be automatically built off of your database schema, like ASP.NET Dynamic Data

如果您的系统只是CRUD且没有任何行为,请尝试一个可以自动构建数据库模式的脚手架系统,如ASP.NET动态数据

#4


Within an MVC design you would typically have a mapping from Repository -> Domain Models and then from Domain Models -> View Models. The View Models often contain Domain Objects though.

在MVC设计中,您通常会从Repository - > Domain Models,然后从Domain Models - > View Models获得映射。视图模型通常包含域对象。

#5


The answer is quite straight :

答案很简单:

  • The domain objects have domain oriented design and methods.
  • 域对象具有面向领域的设计和方法。

  • The view objects have view/control oriented design and methods.
  • 视图对象具有面向视图/控件的设计和方法。

If you can use your domain objects in the view, they are maybe not quite domain oriented.

如果您可以在视图中使用域对象,则它们可能不是面向域的。

#6


Domain objects are really the internal logic inside your business logic layer. They shouldn't be directly exposed to your clients (UI layer). Instead, encapsulate the usage of your domain model into application services. The application services can utilize lightweight DTOs and/or command objects to pass data and intent between the client and the domain model.

域对象实际上是业务逻辑层中的内部逻辑。它们不应直接暴露给您的客户(UI层)。相反,将域模型的使用封装到应用程序服务中。应用程序服务可以利用轻量级DTO和/或命令对象在客户端和域模型之间传递数据和意图。