哪种设计模式适合将关系数据转换为领域模型?
问题
我有一些代码将以关系形式存储的数据转换为域模型。源不是 RDBMS,而是一组生成的“表”类。这些表类类似于 java.sql.ResultSet
,每个表类代表一组数据:订单、订购的商品、交货、发票、序列号。
转换代码通过迭代表从头开始创建域模型的层次结构。它创建适当的模型对象,将它们挂接到其他模型对象等等。完成后,它返回域模型(订单列表)。
问题在于转换代码都被塞进一个类中并涵盖数据的不同方面,因此很难进行单元测试、查找错误或扩展它。我需要维护这段代码多年,并且真的想以某种方式将其拆分,但我不确定哪种设计模式可以很好地适用于这里。
引入
我倾向于将代码重构为访问者模式:
- 一个容器类,该类公开对表对象的引用(例如
getOrdersTable()
、getOrderItemsTable()
- )该容器类有多个访问者类。每个访问者都涵盖源数据的一个方面:一个方面创建订单对象本身,另一个方面创建交付对象并将它们挂接到相应的订单对象中,等等。
但是,我不确定以下问题:
- 访问者不仅可以使用他们访问的表对象,还可以使用其他访问者创建的对象(后者都可以通过订单列表访问)这是领域模型的根)。因此,调用访问者的顺序很重要。
- 访问者模式通常在节点层次结构的上下文中进行解释,但我不会让他们访问层次结构,他们会创建一个层次结构。
问题
Visitor 是一个不错的选择,还是您会选择其他众所周知的模式?或者在这种情况下,没有任何设计模式可以很好地应用,我应该避免(错误)使用模式术语?
上述任何问题对于访问者来说是否不常见?如果是这样,您认为无论如何实现 Visitor 都会使代码变得混乱吗?毕竟,模式是为了满足直观期望并提高代码的意义。
上下文信息
- 我可以安全地将方法添加到表类(每个类由一个抽象生成的类和一个用于手动修改的子类组成)或让它们实现接口,但不能修改其公共超类或引入新的超类。
- 该组表相对稳定,但可能会添加新列。另外,转换逻辑本身也有一定程度的变化(例如跳过哪些命令,或者映射数据的特殊情况)
- 域模型本身相对干净,我无意以非向后兼容的方式更改它或甚至完全替换它。
- 这是关于Java代码的。
- 不需要线程安全。
Problem
I have some code which turns data stored in relational form to a domain model. The source is not an RDBMS, but a set of generated 'table' classes. These table classes are comparable to a java.sql.ResultSet
, each representing one set of data: orders, ordered items, deliveries, invoices, serial numbers.
The conversion code creates a hierarchy of domain models from scratch by iterating over the tables. It creates appropriate model objects, hooking them into other model objects and so forth. Once finished, it returns the domain model (a list of orders).
The problem is that the conversion code is all shoved into one class and covers different aspects of the data, so it's really hard to unit test, find bugs or extend it. I need to maintain this code for years and really want to split it up somehow, but I'm unsure as to which design pattern might apply nicely here.
Idea
I'm leaning towards refactoring the code into the visitor pattern:
- introduce a container class that exposes references to the table objects (e.g.
getOrdersTable()
,getOrderItemsTable()
) - create multiple visitor classes for this container class. Each visitor covers one aspect of the source data: one that creates the order objects themselves, another creating the delivery objects and hooking them into the respective order objects, and so forth.
I am, however, unsure about the following issues:
- the visitors would not only work with the table objects they visit, but also with objects created by other visitors (where the latter are all accessible by the order list which is the root of the domain model). Thus, the order in which visitors are invoked is important.
- The visitor pattern is often explained in the context of node hierarchies, but I would not have them visit a hierarchy, they would create one.
Questions
Is Visitor a good choice, or would you choose another well-known pattern? Or is this a case where no design pattern applies really well and I should avoid (mis)using pattern terminology?
Is any of the issues above unusual for visitors? If so, do you think implementing Visitor anyway would make the code confusing? After all, patterns are about matching intuitive expectations and improving the meaningfulness of code.
Context info
- I can safely add methods to the table classes (each consists of an abstract generated class and a subclass intended for manual modification) or have them implement interfaces, but cannot modify their common superclasss or introduce a new one.
- The set of tables is relatively stable, but new columns will likely be added. Also, there is some degree of change in the conversion logic itself (e.g. which orders to skip, or special cases for mapping data)
- The domain model itself is relatively clean, I have no intention to change it in non-backwards-compatible ways or even replace it entirely.
- This is about Java code.
- Thread safety is not required.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您还没有读过,我建议您阅读 Martin Fowler 的书 企业应用程序架构模式
正如您所说,访问者模式实际上是一种将操作应用于已经以某种方式结构化的对象的模式 - 正如您所说,您还没有实现。
在 Martin Fowler 的术语中,我认为您想要的是一个 Data Mapper ,它与您当前的实现类似。
对我来说,诀窍是确保您的实现在编写时考虑到可维护性和可测试性。您可能想要练习一些 TDD 来帮助您实现目标,但总而言之,我认为您应该看看哪些功能可以分为“帮助程序”类,这些类可以简单地进行单元测试
例如,您可能决定拥有一个数据访问对象对于每个“表”,留下主 DataMapper 类来控制域模型的最终构造
If you haven't already I suggest you get a copy of Martin Fowler's book Patterns of Enterprise Application Architecture
The visitor patterns as you say is really a pattern for applying an operation to objects already put structured in some way - as you say you're not there yet.
In Martin Fowler's terminology I think what you want is a Data Mapper which is similar to your current implementation.
For me the trick is to make sure your implementation is written with maintanibility and testability in mind. You may want to practice some TDD to help you achieve your goals but in summary I think your should look at what functionality can be separated out into 'helper' classes which can be unit tested simply
For example you may decide to have a Data Access Object for each 'table' leaving the main DataMapper class to control the final construction of the Domain Model
领域对象或业务对象模式将满足您的需求。
请浏览业务对象
http://www.corej2eepatterns.com/Patterns2ndEd/BusinessObject.htm
域存储模式 if您的应用程序本质上更复杂
http://www.corej2eepatterns.com/Patterns2ndEd/DomainStore.htm< /a>
Domain Object or Business Object Pattern will suffice your need.
Please go through Business Object
http://www.corej2eepatterns.com/Patterns2ndEd/BusinessObject.htm
Domain Store Pattern if you application is more complex in nature
http://www.corej2eepatterns.com/Patterns2ndEd/DomainStore.htm