Java 值对象、实体和字典类型的DDD建模
我想把我的问题带给更多的听众,因为我们已经在公司讨论了一段时间,但找不到答案 假设我们有事务对象,它是聚合根。 在交易中我们有钱,这是价值对象Java 值对象、实体和字典类型的DDD建模,java,hibernate,jpa,domain-driven-design,Java,Hibernate,Jpa,Domain Driven Design,我想把我的问题带给更多的听众,因为我们已经在公司讨论了一段时间,但找不到答案 假设我们有事务对象,它是聚合根。 在交易中我们有钱,这是价值对象 class Transaction { private Money money; // other stuff } 及 这样的事务可以持久化(我们使用hibernate)到db到简单的表事务中 一切都会很好但是。。。客户要求我们在数据库中有货币表(我们称之为字典表),每个有钱的表(包括交易)都需要指向货币表: +------------
class Transaction {
private Money money;
// other stuff
}
及
这样的事务可以持久化(我们使用hibernate)到db到简单的表事务中
一切都会很好但是。。。客户要求我们在数据库中有货币表(我们称之为字典表),每个有钱的表(包括交易)都需要指向货币表:
+-----------------+ +-----------------+
| transaction | |curency |
+-----------------+ +-----------------+
|id : bigint | +---> | id: bigint |
|amount: decimal | | | code: varchar |
|curr_id: bigint | ----+ | name: varchar |
|other... | +-----------------+
+-----------------+
所以从现在开始,Money对象应该是这样的:
class Money {
private BigDecimal amount;
private Currency currency;
}
从现在起,我们不能称之为值对象:(或者我们可以吗?这也使我们持久化对象的方式变得复杂,因为我们需要编写自己的自定义类型,因此不能再使用hibernate Embeddeble了。当然,我们不是第一个遇到这种问题的人,因为字典类型在使用中很流行,问题是,如何在ddd建模的范围内处理它们 在处理地址时,我们将面临类似的问题。因此,我们知道我们有像Country和FederalState这样的字典(它们是分层的)。我们还知道我们应用程序中的许多对象(例如Institute)有自己的地址,但也与FederalState有联系。因此,在simpe情况下,我们将有:
class Institution {
Address address;
// ...
}
在哪里
但我们需要它与fedral state表有关系,因此地址如下所示:
class Address {
String street;
String houseNo;
// etc..
FederalState federalState;
}
所以我们再次面临同样的问题,地址从此不再是价值对象。
我们知道如何在技术上做到这一点,但从od ddd的角度看,什么是正确的方法?“从od ddd的角度看,什么是正确的方法?”
首先,使用字典实体并没有错。可能只是因为与字符串值不同,使用字典实体的关系:
撇开上述两种情况不谈,业务需求可能会强加这种设计。例如,对于
货币
情况:当表示为一个实体时,允许定义汇率
关系,其本身可能受制于一种存储汇率随时间变化的方法。具有
状态
DICT对于(可能的未来)扩展处理不同的销售税政策或立法限制(产品/服务在某些州是不允许的,请参见“药用”杂草等等)来说,这是一个很好的基础。“从现在起,我们不能称之为价值对象:(”-为什么?@guillaume31因为,现在它有了自己的表,它获得了更高的地位,它可能会觉得被冒犯?在你的问题中,我看不到一个钱表。此外,判断一个对象是否是值对象与数据库表几乎没有什么关系。@guillaume31不仅是“任何时刻的性质”,而且还与“需要跟踪进化”——如果其属性的变化足够重要,可以在其进化过程中跟踪,那么我们所说的肯定是“实体”而不是“价值”"。您的模型中很可能有一个值对象,从持久性世界的角度来看,它是一个实体,这很好,只要它在模型中保持一个值。并非所有的值对象都必须是可嵌入的,否则您永远无法在关系数据库中有效地建模一组值。现在,在您的Currency-FederalState示例中,只要货币只引用州的ID,您就可以了。
class Institution {
Address address;
// ...
}
class Address {
String street;
String houseNo;
// etc..
String federalState;
String country;
}
class Address {
String street;
String houseNo;
// etc..
FederalState federalState;
}