【问题标题】:What is this ORM pattern called这个 ORM 模式叫什么
【发布时间】:2018-06-29 10:58:40
【问题描述】:

我已经习惯了像 JPA 这样的框架在数据库行和 Java 对象之间进行对象关系映射。

但是,在我的公司中,我们使用 ORM 的专有框架,它不使用实体类来表示实体,而只是一个 java.util.Map 类,其中数据库列值映射到它们的名称。

通常,这样的地图还可以作为表示层呈现表单的模型。再次发布表单会将参数作为映射注入处理程序方法。这是 2000 年初的旧框架。

即使认为在实体类上使用映射听起来像是过时和反模式,但我实际上喜欢这个模型的“动态”性质。在地图被传递到表示层之前,您可以轻松地将任何数据添加到业务逻辑层中的地图,并且它成为表单的一部分,只需更改模板本身。如有必要,它允许您用任何东西来增强任何实体。这最终很有用,例如,如果您必须在某些条件下为某个字段显示某些通知。您只需检查条件,如有必要将通知添加到地图,如果地图中存在,则在模板中渲染它。如果我使用实体类,我将需要使用属性重构实体类接口,这甚至不是实体的真实属性。业务逻辑充满了这些特殊条件,并且不断发展。

这是一种危险的想法吗?我是否爱上了反模式?或者在复杂的业务领域中使用这种模式是否合理,这种模式有名称吗?

【问题讨论】:

    标签: java jpa design-patterns orm architecture


    【解决方案1】:

    我不知道适合您描述的模式,但是在实体类上使用Maps 也有缺点。

    在地图被传递到表示层之前,您可以轻松地将任何数据添加到业务逻辑层中的地图,它成为表单的一部分,只需更改模板本身。

    您认为的优势意味着您永远无法确定Map 处于哪个状态。如果您通过服务 1 加载实体,则地图可能包含一些值。如果您通过另一个服务 2 加载相同的实体,它可能不包含某些值。 Map 的状态是特定于用例的。

    由于您使用的是Map,这也意味着从客户的角度来看,每个属性都具有相同的类型,例如Map<String, Object>。因此,如果您在代码中看到实体映射,您还必须知道它具有哪种类型。不知道这会很困难,例如计算订单总数。

    只要你是唯一一个在代码上工作的人,并且你知道所有Map 状态,你就会认为它既灵活又快速。如果您有一段时间没有编写此类代码,您可能会忘记Map 可以具有的不同状态。然后,您必须检查每个用例的整个代码,以查看某些代码是否添加或删除了属性,或者只是替换了属性类型。

    因此,请尝试从文档的角度考虑该设计。专用实体类的最大优点是它是命名的。你可以给一个类一个名字,从而一个意义。例如

    public class PlacedOrder { ... }
    public class Refund { ... }
    

    您还可以轻松地将 javadoc 添加到该类中,以提供有关该类在您的上下文中的含义的更详细信息。这通常称为Ubiquitous Language。我经常只使用术语域语言,因为它更容易说。

    根据我的经验,这种设计通常会导致系统难以维护。在代码库很小的时候,你真的很快。但这并不令人惊讶,因为您经常通过不应用clean code 原则来节省文档时间。

    由于编译器无法检查类型,您只会在运行时发现类型问题。这意味着您必须创建一个大的test harness,因为测试还必须发现编译器会报告的错误。或者你只是开发试错法,但这不是我的方式,也不能让我满意。

    【讨论】:

    • 其实它是一种特殊的map,它实现了实体类接口(某些属性的setter和getter)和map接口,所以你可以使用,但不限于实体接口。
    猜你喜欢
    • 2011-02-20
    • 1970-01-01
    • 2016-09-13
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    相关资源
    最近更新 更多