【问题标题】:Builder Pattern and Persistence构建器模式和持久性
【发布时间】:2012-02-22 15:18:51
【问题描述】:

我为我的项目的几个类(多个参数、一些强制性、一些可选等)使用了 Builder 模式。这些类是不可变的(没有 setter,集合 getter 的深拷贝)。

我现在尝试使用持久性框架将这些对象存储在数据库中,该框架使用默认构造函数 + 设置器构造对象。它不太喜欢我的 Builders!

我不想将这种设置降级为 POJO,并失去当前设计的优势(灵活性、不变性、构造安全性)。

我欢迎任何关于可以在这种情况下使用的变通办法的反馈(我可以包装这些类中的每一个,但这会使类的数量增加一倍,我宁愿避免这种情况)。

一个post 实际上指出这是构建器模式的一个特定缺点。

编辑

一个answer 建议使用私有构造函数/设置器,但这仅在类的字段不是最终字段时才有效,这不是我的情况。

最终编辑

谢谢大家。
我认为我的最终解决方案看起来像这样并且工作正常(为了记录,我正在使用 MongoDB + Morphia):

class AClass {
    private final String aField;
    private final AClass() {
        aField = "";
    }
    //Standard builder pattern after that - no setters (private or public)
}

【问题讨论】:

  • 不能包含 setter 和默认构造函数,但将它们设为私有吗?
  • 好问题 - 我会检查一下
  • 我知道 Hibernate 可以使用私有的 setter 和构造函数,只是想知道你是否有针对特定情况的反对意见。
  • 如果可行的话,没有什么反对的。立即测试。
  • 如下所述,我的类中的字段是最终的,所以我不能使用私有设置器。否则,您的解决方案将起作用。问题已编辑。

标签: java design-patterns persistence


【解决方案1】:

正如我在评论中所说:您可以包含默认构造函数和所有必需的设置器,但将它们设为私有。这样您就可以保持对象的不变性,但是像 Hibernate 这样的 ORM 将能够在需要时访问方法/构造函数。

其他人也可以使用反射访问这些方法,但是他们也可以使用反射访问私有成员变量。所以添加私有方法并没有真正的缺点。

【讨论】:

  • 如果这些字段不是最终的,那就可以了。但如果它们是,那么出于明显的原因,我不能使用默认构造函数/私有设置器。
  • 如果持久化框架使用反射来访问私有构造函数,那么它应该可以直接设置类字段。即使字段是最终的,这也有效。
  • 将字段设置为 final 显然是使 Object 不可变的一部分,但如果没有用于变异 Object 的公共方法,是否需要将字段设置为 final?除了确保您不会自己在类内部的方法中意外修改值?
  • 经过一些试验和错误之后,它通过创建一个默认构造函数来工作,该构造函数将虚拟值分配给最终字段,而不提供私有设置器(因此我可以将我的字段保留为最终字段),因为框架似乎做了什么@FFJoe 上面说了。
猜你喜欢
  • 2011-05-02
  • 2012-10-07
  • 1970-01-01
  • 2017-01-15
  • 2016-03-07
  • 1970-01-01
  • 2019-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多