保存聚合根而不暴露嵌套实体

时间:2014-08-27 18:20:49

标签: java hibernate persistence domain-driven-design aggregate

我们说我有以下聚合根:

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的汇编程序)放到同一个包中,以便它可以访问这些字段。不喜欢它,因为存储库实现不是域的一部分。

我更喜欢第二种方法,但可能还有其他方法我错过了?

1 个答案:

答案 0 :(得分:1)

我会公开一组OrderItem s。

有一个很好的SO question "What is the best practice for read-only lists in NHibernate",您可以在其中找到如何正确公开馆藏的大量信息。

我认为隐藏OrderItem作为内部状态的集合没有任何顾虑。如果您公开updateQuantity方法,那么应该有可能检查特定项目的数量是否更新。

  

1)添加一个返回复制的集合的方法。我不喜欢它,   因为我们也需要复制每个项目(因为它是   实体,可以改变)这是另一个挑战。

实际上,实体可以被更改,并且它们不是不可变的。值对象应该是不可变的。

在您的示例Order looks like root entity or Aggregate Root and OrderItem looks like Entity. It has an identity within an Order at least so it is definitely not a Value Object.

  

3)使用Hibernate方式:通过java的反射获取项目   存储库。那是作弊”。我也在考虑的方式   创建DTO也是如此,所以我需要一种合法的方式来阅读这些值。

有些人使用两种模式:

  • “干净”域名模型
  • 和“脏数据库依赖”持久性模型。

好吧,我不是这种方法的忠实粉丝。通常我会尝试让我的ORM基于域模型生成合适的数据库结构。

  

2)为项目的每个属性添加getter:

     

更好,因为外面没有人不能改变root的嵌套   实体。但它可以通过大量的虚拟吸气剂打击根类。

为了防止他们受到外部更改,最好不要公开public设置者并至少保留privateprotected

相关问题