域模型是否与数据库模型不同? [英] Are Domain Models different from the Database models?

查看:47
本文介绍了域模型是否与数据库模型不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解DDD中的概念,但在实践中会有些混乱.

I understand the concepts in DDD but in practise it gets a bit confusing.

我正在使用C#,SQL Server和EF.我看到基于我的数据库模式,持久性模型看起来与聚合不同.为了定义整洁,美观的聚合,实体和值对象,我的域模型看起来与数据库模型有所不同.

I am using C#, SQL Server and EF. I see that based on my database schema, the persistence models would look different from my aggregates. In order to define clean, nice aggregates, entities and value objects, my domain models would look different from the database models.

此外,如果我尝试合并这2个对象,那么我将以某种方式尝试根据技术而非领域来设计领域模型.

Moreover, if I try to merge these 2 then somehow I try to design my domain models more based on technology, not on domain.

也许是一个更具体的例子,例如:

Maybe a more concrete example would be for example:

  • 如果该ID仅用于数据库,我是否需要在实体中添加一个ID字段?

  • Do I need to add an ID field in the entity if that id is used just for DB?

如果出现Many2Many关系,也会变得很棘手

In case of Many2Many relationships it can also get tricky

这两个模型是否不同,并且存储库的实现必须将db模型转换为域模型,或者我应该使域模型与EF使用的模型相同?

Are these 2 models different and the implementation of the repository must convert db model into domain model or I should make the domain models the same as the models used by EF?

推荐答案

从DDD开始时,这是一个常见问题.

That's a common issue when you start with DDD.

它们完全是 个独立的东西.

They are completely seperate things.

域模型是一个抽象.它不应该关心您正在使用的技术,也不代表数据库表,文档,类,函数等.

A Domain Model is an abstraction. It should not concern itself about the technology that you are using and it doesn't represent database tables, documents, classes, functions etc.

域模型表示概念,依赖性和这些概念之间的相互作用.

The Domain Model represents concepts, dependencies and interactions between these concepts.

技术用于域模型实施.

可以使用不同的技术来实现相同的域模型.

Different technologies can be used to impelement the same Domain Model.

尽我们所能自由地对您的域模型做我们想做的事,但实际上,我们确实使用一种技术来实现它,有时这会影响到它.

As much as we would like to have the freedom do do whatever we like with your domain models, in practice we do use a technology for it's implementation and sometimes this will affect it.

当然,您可以转储所有freameworks和库,并制定自己的解决方案,从而使您的实现更加容易.即使执行此操作,仍然会剩下您的语言,C#,Java,Rubi等以及它提供的工具.

Of course you can dump all freameworks and libraries and make your own solutions that will make your implementation a lot easier. Even if you do this you are still left with your language, C#, Java, Rubi etc. and the tools that it provides you.

这是一个例子:

比方说,我们开发了一套罐头租赁系统.一个人可以租车.在我们的中,我们有一个 Person 拥有的 Account 帐户,一个 Car 和一个CarRental .

Let's say we develop a system for can rentals. A person can rent a car. In our Domain we have the concept of an Account that a Person has, a Car and a CarRental.

这就是您的域模型.在这一点上,我们不关心语言,数据库或其他任何东西

Thats your Domain Model. At this point we are not concerned with the language, database or anything

现在是域模型实现.

我们将使用C#.现在我们需要决定一个数据库.如果我们决定使用SQL,那么我们可能会决定使用RDBMS的出色功能进行联接,因此我们可以通过以下方式使用整数ID来实现它:

We will use C#. Now we need to decide for a database. If we decide to use SQL, we may decide to use the nice abilities of RDBMS to do joins so we may implement it by using integer IDs this way:

public class Account {
    public int ID { get; private set; }
    // other stuff
}

public class Car {
    public int ID { get; private set; }
    // other stuff
}

public class CarRental {
    public int AccountID { get; private set; }
    public int CarID { get; private set; }
    // other stuff
}

另一方面,我们可能会认为整数ID不好,因为如果您必须与其他系统一起工作并移动数据库和其他内容,则可能会遇到冲突,因此,我们决定考虑一下,然后将电子邮件用作帐户和驾照位置的唯一标识符,作为汽车的唯一标识符:

On the other hand we may decide that integer ID's are not good because you can get collisions if you have to work with other systems and move databases and stuff, so we decide to think a bit and use an e-mail as a unique identifier for the Account and the licence place as a unique identifier for the Car:

public class Account {
    public Email Email { get; private set; }
    // other stuff
}

public class Car {
    public LicencePlace LicencePlace { get; private set; }
    // other stuff
}

public class CarRental {
    public Email AccountEmail { get; private set; }
    public LicencePlace CarLicencePlace { get; private set; }
    // other stuff
}

如果我们遵循DDD并将您的实体正确地划分为 Aggregates ,则您无需在它们之间进行联接,因为它们不应被加载或在同一转换中进行更改

If we follow DDD and devide your Entities into Aggregates properly, you should not need to do joins between them as they should not be loaded or changes in the same transation.

另一方面,我们可能不希望在同一数据库的顶部构建其他模型(如果使用CQRS,则可能是读取模型,或者我们可能需要提取报告),而使用第二种方法会使这一点变得更加困难因为我们失去了加入联接的能力.

On the other hand, we may wan't to build a different model (read model maybe if we use CQRS, or we may need to extract reports) on top of the same database and using the second approach can make this harder since we loose the ability to do joins.

另一方面,例如,如果我们使用像MongoDB这样的NoSQL数据库,则无法进行联接.因此,使用整数ID不会给我们带来任何价值.

On the other hand, if we use a NoSQL database like MongoDB for example, we don't have the ability to do joins. So using integer ID's doesn't bring us any value.

即使我们决定使用SQL数据库并且不使用整数ID,我们仍然可以使用 Domain Events 并使用它们构建其他模型并进行报告.

Even if we decide use a SQL database and don't use integer ID's we can still use Domain Events and build additional models and reporting using them.

如果我们有一个分布式系统,那么使用联接也不起作用,因此使用整数ID可能根本不会给我们带来任何价值.

Also using joins won't work if we have a distributed system, so using integer ID's may not bring us any value at all.

有时候使用您的技术能力使某些事情变得容易是很方便的,但是我们让它损害我们的 Sytems Domain模型.

Sometimes it's convinient to use the abilities of your technology to make some things easier, but we let it harm our Sytems and Domain Models.

从技术的角度来看,我们最终构建的系统非常健壮,但是他们没有按预期做事,这使他们毫无用处.

We end up building system that are very robust from technological point of view but they don't do the things that they are supposed to do, and that makes them usesless.

无用系统无论实施多么出色,都是无用.

A usesless system is useless no matter how good it's implemented.

如果您尚未阅读

If you haven't read the DDD book, read it. Eric Evans talks about how you technology can either help you or fight you all the way. Eric Evans also talks about how DDD allows for a freedom of implementation so that you don't have to fight your technology.

如果我们一直都在考虑持久性,那么我们倾向于做另一件事.的确,我们大部分时间都在坚持事情,但这并不意味着 Domain Model 是持久保存在数据库中的东西.

Another thing that we tend to do if think all the time about persistence. It's true that we persist things most of the time but that doesn't mean that a Domain Model is something that is Persisted to a database.

当我开始编程时,我开始使用计算机图形和建模应用程序,例如3DsMax和Maya.当我开始编写使用holly 数据库的应用程序时,我真的很奇怪,人们如何不思考和不了解自己的领域,只是坚持不懈地使他们工作并进行交流关于技术.

When I started programming, I started with computer graphics and modeling applications like 3DsMax and Maya. When I started to write applications that use the holly Database it was really weird to me how people don't think and don't know about their domains, just persist stuff and make them work and all they talk about is technology.

如果您不熟悉 数学 ,那么如果您喜欢计算机图形学,就无法编写类似的代码.因此,您首先要学习 数学 .知道其中一些内容之后,就可以编写代码了.

If you are into computer graphics you won't be able to write a single like of code if you don't know Math. So you start with learning Math. After you know some of it, then you can write code.

以游戏为例.您可以设计一个 Physics Engine (物理引擎),该引擎可以对 Domain ofphysics (物理域)进行建模.在此模型中,您将具有诸如工作功率重力加速等概念.无需持久他们.例如,您的确会保留诸如 Player Weight 之类的其他概念,以便 Physics Engine 会知道重力应该如何影响它,但您仍然不知道不能对数据库保持 Power .它仍然是域模型.功能有效等是函数,而不是集合的实体.它们仍然是您的域模型的一部分.

Let's take games for example. You may design a Physics Engine that models the Domain of physics . In this model you will have concepts like Work, Power, Gravity, Acceleration etc. It's not necessary to persist them. You do persist other conceps like Weight of your Player for example so that the Physics Engine will know how gravity should affect it, but still you don't persist Power to the database. It's still a Domain Model. Power, Workd etc are functions, not entities of aggregates. They are still part of your Domain Model.

假设您不想构建物理引擎,而 如果您不想构建物理引擎,则必须了解物理.物理很复杂.即使您是精通EF或SQL的编程者,也不会帮助您构建物理引擎.了解物理域并能够对其进行 域模型 ,然后 实施是关键.

Let's say you wan't to build a Physics engine The thing is that if you wan't to build a Physics Engine you have to know Physics. Physics is complex. Even if you are a really good programming knowing in EF or SQL of whatever, it won't help you build Physics engines. Knowing the Domain of physics and being able to make a Domain Model of it and then Implement it is the key.

如果您想真正感受到实施中的域模型之间的区别,请检查,在您执行任何实现之前,此域可能会引起您的注意.

If you want to really feel the difference between a Domain model from Implementation, check this out, This domain can blow your mind before you get to any implementation.

也请查看本文关于使用以下方法对实体进行建模DDD.

Also check this article on modeling entities with DDD.

编辑

这是另一篇文章解释了NHibernaty和用于领域建模的EntityFramework之间的区别.

Here is another article that explains differences between NHibernaty and EntityFramework for Domain Modeling.

这篇关于域模型是否与数据库模型不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆