简体   繁体   English

值与实体对象(域驱动设计)

[英]Value vs Entity objects (Domain Driven Design)

I have just started reading DDD.我刚刚开始阅读 DDD。 I am unable to completely grasp the concept of Entity vs Value objects.. Can someone please explain the problems (maintainability, performance.. etc) a system could face when a Value object is designed as a Entity object?我无法完全掌握实体与值对象的概念。有人可以解释当值对象被设计为实体对象时系统可能面临的问题(可维护性、性能等)吗? Example would be great...例子会很棒......

Reduced to the essential distinction, identity matters for entities, but does not matter for value objects.归结为本质区别,身份对实体很重要,但对值对象无关紧要。 For example, someone's Name is a value object.例如,某人的姓名是一个值对象。 A Customer entity might be composed of a customer Name (value object), List<Order> OrderHistory (List of entities), and perhaps a default Address (typically a value object).客户实体可能由客户名称(值对象)、List<Order> OrderHistory(实体列表)和可能的默认地址(通常是值对象)组成。 The Customer Entity would have an ID, and each order would have an ID, but a Name should not;客户实体将有一个 ID,每个订单都有一个 ID,但名称不应; generally, within the object model anyway, the identity of an Address probably does not matter.通常,无论如何,在对象模型中,地址的身份可能无关紧要。

Value objects can typically be represented as immutable objects;值对象通常可以表示为不可变对象; changing one property of a value object essentially destroys the old object and creates a new one, because you're not as concerned with identity as with content.更改值对象的一个​​属性本质上会破坏旧对象并创建一个新对象,因为您不像内容那样关心身份。 Properly, the Equals instance method on Name would return "true" as long as the object's properties are identical to the properties of another instance.正确地,只要对象的属性与另一个实例的属性相同,Name 上的 Equals 实例方法就会返回“true”。

However, changing some attribute of an entity like Customer doesn't destroy the customer;但是,更改诸如 Customer 之类的实体的某些属性并不会破坏该客户; a Customer entity is typically mutable. Customer 实体通常是可变的。 The identity remains the same (at least once the object has been persisted).身份保持不变(至少在对象被持久化后)。

You probably create value objects without realizing it;您可能在没有意识到的情况下创建了值对象; anytime you are representing some aspect of an Entity by creating a fine-grained class, you've got a value object.任何时候你通过创建一个细粒度的类来表示实体的某些方面,你就有了一个值对象。 For example, a class IPAddress, which has some constraints on valid values but is composed of simpler datatypes, would be a value object.例如,一个类 IPAddress 对有效值有一些限制,但由更简单的数据类型组成,将是一个值对象。 An EmailAddress could be a string, or it could be a value object with its own set of behaviors. EmailAddress 可以是字符串,也可以是具有自己的行为集的值对象。

It's quite possible that even items that have an identity in your database don't have an identity in your object model.很有可能即使在您的数据库中具有标识的项目在您的对象模型中也没有标识。 But the simplest case is a composite of some attributes that make sense together.但最简单的情况是将一些有意义的属性组合在一起。 You probably don't want to have Customer.FirstName, Customer.LastName, Customer.MiddleInitial and Customer.Title when you can compose those together as Customer.Name;当您可以将它们组合为 Customer.Name 时,您可能不想拥有 Customer.FirstName、Customer.LastName、Customer.MiddleInitial 和 Customer.Title; they'll probably be multiple fields in your database by the time you think about persistence, but your object model doesn't care.当您考虑持久性时,它们可能会成为您数据库中的多个字段,但您的对象模型并不关心。

Any object that is collectively defined by all of it attributes is a value object.任何由其所有属性共同定义的对象都是值对象。 If any of the attributes change you have a new instance of a value object.如果任何属性发生变化,您将拥有一个值对象的新实例。 This is why value objects are defined as immutable.这就是为什么值对象被定义为不可变的。

If the object is not fully defined by all of its attributes then there are a subset of attributes that make up the identity of the object.如果对象没有完全由其所有属性定义,则存在组成对象标识的属性子集。 The remaining attributes can change without redefining the object.其余属性无需重新定义对象即可更改。 This kind of object cannot be defined at immutable.这种对象不能在 immutable 中定义。

A simpler way of making the distinction is to think of value objects as static data that will never change and entities as data that evolves in your application.一种更简单的区分方法是将值对象视为永远不会改变的静态数据,将实体视为在应用程序中发展的数据。

Value Types :值类型:

  • Value types do not exist on his own, depends on Entity types.值类型本身不存在,取决于实体类型。
  • Value Type object belongs to an Entity Type Object.值类型对象属于实体类型对象。
  • The lifespan of a value type instance is bounded by the lifespan of the owning entity instance.值类型实例的生命周期受拥有实体实例的生命周期的限制。
  • Three Value types: Basic(primitive datatypes), Composite(Address) and Collection(Map, List, Arrays)三种值类型:基本(原始数据类型)、复合(地址)和集合(映射、列表、数组)

Entities:实体:

  • Entity types can exist on his own (Identity)实体类型可以独立存在(Identity)
  • An entity has its own life-cycle.实体有自己的生命周期。 It may exist independently of any other entity.它可以独立于任何其他实体而存在。
  • For example: Person, Organisation, College, Mobile, Home etc.. every object has its own identity例如:人、组织、学院、手机、家庭等。每个对象都有自己的身份

I don't know if the following is correct, but I would say that in the case of an Address object, we want to use it as a Value Object instead of an Entity because changes to the entity would be reflected on all linked objects (a Person for instance).我不知道以下是否正确,但我会说,在 Address 对象的情况下,我们希望将其用作值对象而不是实体,因为对实体的更改将反映在所有链接对象上(例如一个人)。

Take this case: You are living in your house with some other people.以这种情况为例:您和其他一些人住在自己的房子里。 If we would use Entity for Address, I would argue that there would be one unique Address that all Person objects link to.如果我们将 Entity 用于 Address,我认为所有 Person 对象都链接到一个唯一的 Address。 If one person moves out, you want to update his address.如果一个人搬出去,你想更新他的地址。 If you would update the properties of the Address Entity, all people would have a different address.如果您要更新地址实体的属性,则所有人都将拥有不同的地址。 In the case of a Value Object, we would not be able to edit the Address (since it is immutable) and we would be forced to provide a new Address for that Person.在值对象的情况下,我们将无法编辑地址(因为它是不可变的)并且我们将被迫为该人提供一个新地址。

Does this sound right?这听起来对吗? I must say that I was/am also still confused about this difference, after reading the DDD book.我必须说,在阅读了 DDD 书之后,我仍然/仍然对这种差异感到困惑。

Going one step further, how would this be modelled in the database?更进一步,这将如何在数据库中建模? Would you have all properties of the Address object as columns in the Person table or would you create a separate Address table that would also have a unique identifier?您是否将 Address 对象的所有属性都作为 Person 表中的列,或者您是否会创建一个单独的 Address 表,该表也将具有唯一标识符? In the latter case, the people living in the same house would each have a different instance of an Address object, but those objects would be the same except for their ID property.在后一种情况下,住在同一栋房子里的人每个人都有一个不同的 Address 对象实例,但这些对象除了 ID 属性外都是相同的。

address can be entity or value object that depends on the busiess process.地址可以是实体或值对象,这取决于繁忙的进程。 address object can be entity in courier service application but address can be value object in some other application.地址对象可以是快递服务应用程序中的实体,但地址可以是其他应用程序中的值对象。 in courier application identity matters for address object在快递申请中地址对象的身份问题

3 distinction between Entities and Value Objects 3 EntitiesValue Objects区别

  • Identifier vs structural equality: Entities have identifier,entities are the same if they have the same identifier.标识符 vs 结构相等:实体有标识符,如果实体有相同的标识符,则实体是相同的。 Value Objects on beyond the hand have structural equality, we consider two value objects equal when all the fields are the same.超越手上的值对象具有结构相等性,当所有字段都相同时,我们认为两个值对象相等。 Value objects cannot have identifier.值对象不能有标识符。

  • Mutability vs immutability: Value Objects are immutable data structures whereas entities change during their life time.可变性与不变性:值对象是不可变的数据结构,而实体在其生命周期中会发生变化。

  • Lifespan: Value Objects Should belong to Entities Lifespan:值对象应该属于实体

I asked about this in another thread and I think I'm still confused.我在另一个线程中询问了这个问题,我想我仍然感到困惑。 I may be confusing performance considerations with data modelling.我可能会将性能考虑与数据建模混淆。 In our Cataloging application, a Customer doesn't change until it needs to.在我们的编目应用程序中,客户在需要时不会更改。 That sounds dumb - but the 'reads' of customer data far outnumber the 'writes' and since many many web requests are all hitting on the 'active set' of objects, I don't want to keep loading Customers time and again.这听起来很愚蠢 - 但是客户数据的“读取”远远超过“写入”,并且由于许多 Web 请求都在访问“活动集”对象,因此我不想一次又一次地加载客户。 So I was headed down an immutable road for the Customer object - load it, cache it, and serve up the same one to the 99% of (multi-threaded) requests that want to see the Customer.所以我为 Customer 对象走上了一条不可变的道路——加载它,缓存它,并为 99% 的(多线程)请求提供相同的服务,希望看到 Customer。 Then, when a customer changes something, get an 'editor' to make a new Customer and invalidate the old one.然后,当客户更改某些内容时,请“编辑器”创建新客户并使旧客户无效。

My concern is if many threads see the same customer object and it is mutable, then when one thread starts to change it mayhem ensues in the others.我担心的是,如果许多线程看到同一个客户对象并且它是可变的,那么当一个线程开始更改时,其他线程就会发生混乱。

My problems now are, 1) is this reasonable, and 2) how best to do this without duplicating a lot of code about the properties.我现在的问题是,1) 这是否合理,以及 2) 如何最好地做到这一点,而无需复制大量有关属性的代码。

In a very simple sentence I can say, we have three types of equality:用一个非常简单的句子我可以说,我们有三种类型的平等:

  • Identifier equality : a class has id filed and two objects are compared with their id field value.标识符相等:一个类有 id 字段,两个对象与它们的 id 字段值进行比较。
  • Reference equality : if a reference to two objects has a same address in memory.引用相等:如果对两个对象的引用在内存中具有相同的地址。
  • Structural equality : two objects are equal if all members of them are matched.结构相等:如果两个对象的所有成员都匹配,则它们相等。

Identifier equality refers only to Entity and structural equality refers to Value Object only.标识符相等仅指实体,结构相等仅指值对象。 In fact Value Objects do not have id and we can use them interchangeably.事实上,值对象没有 id,我们可以互换使用它们。 also value objects must be immutable and entities can be mutable and value objects will not have nay table in database.值对象也必须是不可变的,实体可以是可变的,值对象在数据库中不会有表。

An entity:一个实体:

  • has an identity有身份

  • contains value objects包含值对象

  • may contain other entities可能包含其他实体

  • can be mutable可以是可变的

A value object:一个值对象:

  • does not have an identity没有身份

  • must be immutable必须是不可变的

Consider the following examples from Wikipedia , in order to better understand the difference between Value Objects and Entities:考虑以下来自Wikipedia 的示例,以便更好地理解值对象和实体之间的区别:

Value Object: When people exchange dollar bills, they generally do not distinguish between each unique bill;价值对象:人们在兑换美元钞票时,一般不区分每张独特的钞票; they only are concerned about the face value of the dollar bill.他们只关心美元钞票的面值。 In this context, dollar bills are Value Objects.在这种情况下,美元钞票是值对象。 However, the Federal Reserve may be concerned about each unique bill;但是,美联储可能会关注每张独特的钞票; in this context each bill would be an entity.在这种情况下,每项法案都是一个实体。

Entity: Most airlines distinguish each seat uniquely on every flight.实体:大多数航空公司在每个航班上都唯一区分每个座位。 Each seat is an entity in this context.在这种情况下,每个座位都是一个实体。 However, Southwest Airlines, EasyJet and Ryanair do not distinguish between every seat;但是,西南航空、易捷航空和瑞安航空不区分每个座位; all seats are the same.所有座位都一样。 In this context, a seat is actually a Value Object.在这种情况下,座位实际上是一个值对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM