假设我们有一个聚合根对象“Transaction”。在“Transaction”内部,我们有一个值对象“Money”。
class Transaction {
private Money money;
// other stuff
}
和
class Money {
private BigDecimal amount;
private String currency;
}
这样的交易可以使用Hibernate持久化到数据库中的简单表transaction。
+-----------------+
| transaction |
+-----------------+
|id : bigint |
|amount: decimal |
|currency: varchar|
|other... |
+-----------------+
一切都很好,但是...客户要求我们在数据库中拥有货币表(我们称之为字典表),并且每个具有货币的表格(包括交易)都需要指向货币表:
+-----------------+ +-----------------+
| 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 embedable,而是需要编写自己的自定义类型enter link description here。毫无疑问,我们不是第一个面临这些问题的人,因为字典类型在使用中很受欢迎,问题是,在DDD建模范围内如何处理它们。
当处理地址时,我们将面临类似的问题。所以,我们知道我们有像国家和联邦州这样的字典(它们是分层的)。我们也知道我们应用程序中的许多对象(例如Institution)有自己的地址,但也与联邦州有联系。因此,在简单情况下,我们将会有:
class Institution {
Address address;
// ...
}
在哪里
class Address {
String street;
String houseNo;
// etc..
String federalState;
String country;
}
但是我们需要它与联邦州表有关,因此地址将如下所示:
class Address {
String street;
String houseNo;
// etc..
FederalState federalState;
}
我们再次面临着同样的问题,地址不再是值对象。技术上我们知道该如何处理,但从DDD的角度来看,什么是正确的方法?