哪种设计模式适合将关系数据转换为域模型?

时间:2011-01-05 08:20:09

标签: oop design-patterns

问题

我有一些代码可以将以关系形式存储的数据转换为域模型。源不是RDBMS,而是一组生成的“表”类。这些表类与java.sql.ResultSet相当,每个表示一组数据:订单,订购商品,交货,发票,序列号。

转换代码通过迭代表从头开始创建域模型的层次结构。它创建适当的模型对象,将它们挂钩到其他模型对象等等。完成后,它将返回域模型(订单列表)。

问题是转换代码全部被推入一个类并涵盖了数据的不同方面,因此单元测试,发现错误或扩展它真的很难。我需要维护这段代码多年,并且真的想以某种方式将其拆分,但我不确定哪种设计模式可以很好地适用于此。

我倾向于将代码重构为访问者模式:

  • 介绍一个公开对表对象的引用的容器类(例如getOrdersTable()getOrderItemsTable()
  • 为此容器类创建多个访问者类。每个访问者都涵盖了源数据的一个方面:一个创建订单对象本身,另一个创建交付对象并将它们挂钩到相应的订单对象,等等。

但是,我不确定以下问题

  • 访问者不仅可以使用他们访问的表对象,还可以使用其他访问者创建的对象(后者可以通过作为域模型根目录的订单列表访问)。因此,调用访问者的顺序很重要。
  • 访问者模式通常在节点层次结构的上下文中解释,但我不会让他们访问层次结构,他们将创建一个。

问题

  1. 访客是一个不错的选择,还是会选择另一个众所周知的模式?或者这是一个没有设计模式适用的情况,我应该避免(错误)使用模式术语?

  2. 以上任何问题是否对访问者不寻常?如果是这样,你认为实施访问者会使代码混乱吗?毕竟,模式是关于匹配直观期望和提高代码的意义。

  3. 上下文信息

    • 我可以安全地向表类添加方法(每个方法都包含一个抽象生成的类和一个用于手动修改的子类),或者让它们实现接口,但不能修改它们的公共超类或引入一个新类。
    • 这组表相对稳定,但可能会添加新列。此外,转换逻辑本身也有一定程度的变化(例如,要跳过哪个命令,或者映射数据的特殊情况)
    • 域模型本身相对干净,我无意以非向后兼容的方式更改它,甚至无法完全替换它。
    • 这是关于Java代码的。
    • 不需要线程安全。

2 个答案:

答案 0 :(得分:2)

如果你还没有我建议你得到Martin Fowler的书Patterns of Enterprise Application Architecture

的副本

你所说的访问者模式实际上是一种将操作应用于已经以某种方式构建的对象的模式 - 正如你所说,你还没有。

在Martin Fowler的术语中,我认为你想要的是Data Mapper,它类似于你当前的实现。

对我而言,诀窍在于确保您的实现在编写时考虑到可操作性和可测试性。您可能希望练习一些TDD来帮助您实现目标,但总的来说,我认为您应该看看哪些功能可以分成“辅助”类,这些类可以简单地进行单元测试

例如,您可能决定为每个'table'分配一个数据访问对象,离开主DataMapper类来控制域模型的最终构造

答案 1 :(得分:0)

域对象或业务对象模式将满足您的需求。

请浏览Business Object http://www.corej2eepatterns.com/Patterns2ndEd/BusinessObject.htm

域应用程序模式如果您的应用程序本质上更复杂

http://www.corej2eepatterns.com/Patterns2ndEd/DomainStore.htm