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.