问题标签 [value-objects]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
3508 浏览

domain-driven-design - DDD 实体、值对象和数据库映射和更新。不变的矛盾?

我一直在做 DDD 的一个小项目。我到处都看到值对象是不可变的,因此,你不能修改它。只有实体。

我将使用每个人都使用的示例。地址。假设Address 是Customer 实体的 VO(也是根聚合)。如果用户更新他的 Address,这在任何购物车场景中都有效,那么我应该怎么做?我必须修改那个 VO 地址才能将其保存到数据库中。意思是,这个 VO 必须以某种方式具有身份,以便我在数据库中识别它。除非 NHibernate 使用映射来处理它,对。LinqToSql 你不是这种情况。或者我想我必须创建一个新的聚合,其中地址是一个实体?然后几乎在我的聚合中需要地址的任何地方都有一个地址副本?

然而。我仍然无法包装整个 Entity/VO 概念。在我看来,就像在数据库中有表示的所有内容一样,即使您将其用作模型中的 VO,它在某种程度上也是一个实体,因为为了让您持久保存它,您需要某种 KEY 来在数据库中识别它.

归根结底,所有值对象的数据(大部分)都来自数据库。所以我仍然不明白在数据更新的情况下如何使它们不可变。

经过两个月的紧张阅读,我发现整个 DDD 是一个巨大的矛盾问题。阅读所有这些博客,你会明白我在说什么。不幸的是,那里有零演示应用程序,您可以将其用作榜样或指导。它们都受到开发者偏好的影响。然后他们最终攻击了对方的博客。一夜之间-DDD-Guru 的博客确实有助于解决整个社区的困惑。

感谢您的光临。期待建设性的讨论。

0 投票
3 回答
9619 浏览

domain-driven-design - 带有 DB id 和实体的值对象的 DDD 类设计困境

这是一个很长的问题,所以我要直奔主题。这是为了更好地说明问题的伪代码

数据库结构

用户(用户 ID、姓名、姓氏)

地址(AddressID, UserID, Street, City, State, ZipCode) =>多对一用户关系

Phone (PhoneID, UserID, Number, IsPrimary) =>多对一用户关系

领域类

所以,到目前为止,我们对这个领域及其模型有了一个非常基本的表示。

我的问题如下。假设我想更新其中一个地址或修复其中一个数字的区号,因为最初输入的 wnen 拼写错误。

如果我遵循 Evan 关于 DDD 的圣经,值对象应该是不可变的。意思是,在创建后不会更改其属性或字段。如果是这种情况,那么我想,我的所有类都不是 ValueObject,因为我不能仅仅因为电话号码中字符串的一部分错误就重新创建整个 ContactInfo 类。所以,我想这使我所有的类实体?

请记住,我对每个此类都有一个“持久性 ID”,因为它们存储在数据库中。

假设我决定让 Phone 成为一个值对象,因为它很容易在构造函数中重新创建

所以,这就像向用户(agg root)和联系人信息添加一个方法?(得墨忒耳定律)

像...

但我仍然必须处理持久性 id ... grrrrr。真让人头疼。

有时,当我阅读那些博客时,我觉得大多数“ddd 专家”认为价值对象被过度使用,或者我会说被滥用。

这种情况的最佳解决方案是什么?谢谢

0 投票
1 回答
167 浏览

domain-driven-design - 没有身份但不能是 ValueObject 的 DDD 类,因为需要变异(更改)

这个问题在这里有一点背景....

带有 DB id 和实体的值对象的 DDD 类设计困境

由于没有人对我的问题给出令人信服的答案,我将重新表述我的问题,并让回答问题的人受益。也许我没有正确提出我的问题。

我假设此时您阅读了我最初的问题。

所以,ContactInfo 不需要域身份,因为属于 User。没有用户它“不能存在”。它只不过是一个包装其他类和集合(来自数据库)的类(nhibernate 组件),因此,如果我想将其替换为新实例,使其不可变将只是一场噩梦。我需要创建一个具有 n 个参数的完整构造函数,并重新创建整个对象图,只是因为我想更新地址集合中的一条街道。在我看来,愚蠢。

那么,ContactInfo 到底是什么?一个可变的值对象?我很确定 DDD 大师 Evan 有一个关于“可变值对象”的谷歌警报,并且每次出现这两个术语时都会有一个驱魔人发送。

我对此感到非常困惑。几乎卡住了,因为我不想成为“f ... it”有点像程序员,只是因为(但此时我别无选择)而使 ContactInfo 可变。所以,在我最终对 DDD 的概念有自己的解释(和实现)之前,我想有一些意见。

PS:我知道这可能会显得粗鲁,但请不要再复制和粘贴 Evan 书中的答案。既不是抽象的概念。我们都知道 Order 和 Orderline,我们都知道结构和引用类型、Blog、Post 和 Comments。这是一个特定场景,您需要了解有关此问题的所有信息......所以我真的很感激这个场景的具体答案。

谢谢 :)

0 投票
1 回答
642 浏览

domain-driven-design - 我们对 DDD 中的域模型中使用的这些类型的对象有何要求?

我试图找到这个命名问题的解决方案,但我在网络上的任何地方都找不到类似的用法。可能是我们在域模型中有一个设计流程,或者我们根本没有为所谓的“ValueObjects”使用适当的名称。

请阅读下文..

我们使用具有 CQRS 模式的领域驱动设计。下面是域模型的设计方式。

在此处输入图像描述

PS 不相关,但供您参考,我们的应用程序使用 ASP.NET MVC 和控制器与服务层通信。DTO(数据传输对象)被传入/传出到 MVC 控制器,这不在上图中。

问题是我们没有正确使用“ValueObject”。根据 Martin Fowler 的定义,我们的 ValueObject 不是 ValueObject 的真实表示。 http://martinfowler.com/bliki/ValueObject.html

例如,我们的 ValueObjects 有一个身份。

这些值对象只是在命令、聚合根和域实体之间传送数据。例如,AggregateRoot 只是基于域实体创建 ValueObjects,并将这些 ValueObjects 返回给命令层。

以下不是完整的实现。只是一个简单的例子来展示交互

AggregateRoot 扩展方法:

聚合根:

命令 :

我们正在努力为这些所谓的“ValueObjets”找到合适的名称。它们似乎也不是 DTO,而且我们希望能够与服务层中使用的 DTO 区分开来。具体来说,我们想知道可以为这些类型的对象 (ValueObjects) 调用的适当名称。任何想法都非常感谢。

0 投票
3 回答
1028 浏览

c# - DDD 值对象相等,== vs .Equals()

所以我有一个值object,(随意说钱),我想为它实现平等。我知道==.Equals()(引用和数据相等)的预期/默认行为。

不过,在这种情况下,我希望能够比较两个对象,并说它们对于计算是等效的(例如 1m 和 3 ft 是等效的)但是对于持久性(使用NHibernateisDirty我认为取决于相等性)、用户显示和选择货币,我希望它们被认为是不同的。

在这种情况下,我是否应该

  1. ==.Equals()(应该做什么)有不同的行为,
  2. 无论我想在哪里检查等效性,只需检查每个属性(意味着额外的代码)
  3. 实现类似的方法.IsEquivalent()(我不想做后者)
  4. 我想念的其他东西

是否有我应该遵循的最佳实践/模式?谢谢

编辑:我收到了一些关于改变汇率的回应。为了清楚起见,所以更新。让我们说身高,而不是货币

  • 我想澄清一些假设:
  • //忽略:值对象包含十进制金额,字符串/类货币
  • // 忽略:汇率不变。
  • // 忽略:类货币知道它与其他货币的汇率
  • 值对象包含十进制数量,字符串/类单位
  • 班级单位知道它与另一个单位的转换
  • 我不打算扩大费率/转换等

我更关心实践和模式,而不是实施货币。基本上,对人的身高采用相同的方法,其中身高是一个值对象,({1,m} 到 {3,ft},其中 1m 始终“等于”/“等价于”到 3ft)

0 投票
1 回答
190 浏览

spring - Spring:404错误仅将vo类作为spring控制器中的参数

我正在使用 Spring 框架制作网站。问题是仅当我将 VO 作为参数时才会发生 404 错误。我将 VO 作为 @ModelAttribute 放在控制器中。

我用两个表格列一起制作了 VO 的属性。我猜这个问题是因为 1-VO 匹配 2-Table 引起的,因为当我使用 1-VO mathces 1-table 相同的方式时,没有错误。

如果有人知道,请告诉我发生此错误的确切原因。

这里是来源。

这是与 VO 属性匹配的第一个表。

这是与 VO 属性匹配的第二个表。

我用这些 2 表创建了一个 VO 类,以插入与这些表相关的数据。

(省略了设置器/获取器。)

最后,这是控制器源代码部分。

当我删除 @modelAttribute("command") HDW hdw 参数时,控制台会毫无问题地显示“$$Test for hdwControl”。

我应该怎么做才能解决这个问题?

**这里是添加源**

当然,我将 @ModelAttribute 与 html 输入字段进行了匹配。

这是 xml 文件 (iBatis sqlMap) 包含将 HDW 插入数据库的查询。

0 投票
1 回答
2073 浏览

domain-driven-design - 在遵循 DDD 实践时,拥有值对象工厂是否有意义?

最近,我在考虑过去在尝试设计特定领域模型时遇到的一些问题,比如说地址,它可以在给定的上下文中编辑,但在另一个上下文中不可编辑。我目前的思维方式是,我将同时拥有地址的值对象版本和地址的实体,可能附加到客户帐户之类的东西上,以获取它的身份。

现在我意识到,如果我要创建一个新地址,例如当用户输入一个新地址时,我很可能还需要能够继续编辑该地址,也许还需要编辑任何预先存在的地址在相同的有界上下文中。出于这个原因,我可以假设在这个上下文中,地址应该被建模为实体而不是值对象。这引出了我的主要问题,即如果您在修改现有数据集或创建新数据时始终使用实体,那么拥有一个工厂来创建任何值对象是否有意义?

当我遵循这种思路时,对我来说开始出现的规则是,值对象应该只被创建来表示对应用程序来说是静态的东西,或者已经持久化到数据库中的东西,而不是暂时的东西在当前域上下文中。因此,我唯一应该创建任何类型的值对象的地方是当它们在聚合根存储库中或代表它们被重新水化/物化时,用于持久值或在静态值的情况下在服务中。这开始对我来说似乎很清楚,但是让我担心的是,我还没有在其他任何地方读到有人得出相同的结论。不管怎样,我希望有人能证实我的结论或让我直截了当。

0 投票
2 回答
351 浏览

java - Xtend @Data 值对象的附加构造函数

如何在 XTend (XText) 中将辅助构造函数添加到值对象(使用 @Data 注释)?

我尝试了以下方法,但无法编译:

0 投票
1 回答
313 浏览

c# - 应该如何在数据库中保存没有实体的对象

实体“学年”具有可配置的可见工作日,这些工作日在时间计划器中可见或不可见。

我现在看到 2 个可能来保存可见的工作日。

要么我建立一个 N:M 关系:N 个学年有 M 个 VisibleWeekDays

或者我将可见的星期天放在逗号分隔的字段中:“0,2,5”

这些数字是来自 DayOfWeek 枚举的枚举值。

我真的应该采用这种开销方式创建另外 2 个表(junction + VisibleWeekDay 表),只是为了在一个字段中保存一天的索引吗?

您将如何保存可见的工作日?

0 投票
1 回答
1225 浏览

serialization - 如何将值对象存储在关系数据库中?

我正在处理一个大型项目,该项目有许多表示简单(不相关)值的对象。有时这些值是单个字符串,有时它们是两个字符串,有时是一个字符串和一个整数......

目前,我们的关系数据库中有一个“值”表,其中包含以下列:IdCategoryString1String2...、Int1Int2...Double1等。它很方便,但很乱。

这些值都具有以下属性:

  • 每个具有相同属性的对象Category都具有相同的属性(即已键入)。
  • 没有相关的对象(唯一的键是Id主键)。

我们如何摆脱这种混乱局面?在我看来,我们的选择如下:

  1. 只需根据需要继续添加列,并忘记表和对象之间的语义映射。把它堆起来。
  2. 为每个值对象创建一个新表。这将向数据库中添加大量表,其中大多数表少于 6 行。我担心所有这些额外的表都会添加到数据库中。
  3. 仅为这些对象部署一个无模式的数据库(在我们的部署方案中实际上不可能)。
  4. 创建一个带有IdCategory列和 BLOBValue列的表,并将值对象序列化到值列中。这可行吗?

这篇文章重申了我们的选择。使用序列化是否有任何警告或陷阱?有没有我不知道的选项?欢迎咨询。