我们说我有以下聚合根:
class Order {
private Collection<OrderItem> items;
...
public void updateQuantity(int itemId, int quantity) { ... }
}
让我们说我使用普通的SQL来坚持它。问题是:如何在不暴露集合的情况下坚持订单及其项目?我看到了几种我不喜欢的方式:
1)添加一个返回复制的集合的方法。我不喜欢它,因为我们也需要复制每个项目(因为它是实体并且可以更改),这本身就是另一个挑战。
2)为项目的每个属性添加getter:
class Order {
public int getQuantity(int itemId) { ... }
}
最好是因为外面没有人不能改变root的嵌套实体。但它可以通过大量的虚拟吸气剂打击根类。
3)使用Hibernate方式:通过Java在存储库中的反射来获取项目。那是&#34;作弊&#34;。我也在考虑创建DTO的方式,所以我需要一种合法的方式来阅读这些值。
4)使字段使用默认修饰符并将存储库实现(以及DTO的汇编程序)放到同一个包中,以便它可以访问这些字段。不喜欢它,因为存储库实现不是域的一部分。
我更喜欢第二种方法,但可能还有其他方法我错过了?
答案 0 :(得分:1)
我会公开一组OrderItem
s。
有一个很好的SO question "What is the best practice for read-only lists in NHibernate",您可以在其中找到如何正确公开馆藏的大量信息。
我认为隐藏OrderItem
作为内部状态的集合没有任何顾虑。如果您公开updateQuantity
方法,那么应该有可能检查特定项目的数量是否更新。
1)添加一个返回复制的集合的方法。我不喜欢它, 因为我们也需要复制每个项目(因为它是 实体,可以改变)这是另一个挑战。
实际上,实体可以被更改,并且它们不是不可变的。值对象应该是不可变的。
中3)使用Hibernate方式:通过java的反射获取项目 存储库。那是作弊”。我也在考虑的方式 创建DTO也是如此,所以我需要一种合法的方式来阅读这些值。
有些人使用两种模式:
好吧,我不是这种方法的忠实粉丝。通常我会尝试让我的ORM基于域模型生成合适的数据库结构。
2)为项目的每个属性添加getter:
更好,因为外面没有人不能改变root的嵌套 实体。但它可以通过大量的虚拟吸气剂打击根类。
为了防止他们受到外部更改,最好不要公开public
设置者并至少保留private
或protected
。