Reputation: 33
I am storing and parsing xml files, those files evolve over time so when stored I also store the version of the format.
When I load an xml I get the version of the file and based on this version I use a specific java class to process it. The xml format is changing every few weeks so a new class is being created and added to the list of classes. I can load any version of an xml any time (e.g. today I can load xml files created two years ago with version v02 while currently is at version v26)
Is there a design pattern for this kind of problem ? Is there a design pattern using dependency injection for this kind of problem ?
Currently I have a java interface defining a DocumentParser
and I have several DocumentParsers each in different package (e.g. com.parsers.v1.DocumentParserImpl
) and I have a provider class DocumentParserProvider
to supply the proper parser using the version (e.g. public DocumentParser get(String version);
). The interface api never changes, that is we always ask the same thing from our interface.
Is there a better way to do it or is there a name for this problem?
Upvotes: 3
Views: 4241
Reputation: 12882
Depending on the steps involved in the actual parsing, you could also apply Template Method pattern (related to Strategy):
This is kind of like applying Don't Repeat Yourself (DRY) and refactoring out the common parts of parsing into the template method, and defining polymorphic methods for the parts that vary. Applied to the context of your parsers:
If most of the repeating code is isolated to the template method, you can stop there. As I wrote in my comment on @Jay's answer, you should first look to see if there's some pattern in what is different in each version of your XML file and how it affects the parsing. You could
parseOperation
s for only the parts that tend to vary (extract method refactoring), with the template method parse
calling them at the right time.parseOperation
s themselves repeat. If so, then put the repeated code inside of other classes (extract class refactoring to use composition). Ideally, if any copy/paste repetition occurs, extract it into some kind of ParseUtility class (or it could be static functions in the abstract class depending on how you'd test/reuse them).This refactoring approach may seem like a lot of work depending on what has changed over the versions of the XML file. The investment could pay off in the case of bug fixes. For example, using only Strategy (and no refactoring of the parts that repeat), if you find a bug in v1
and you have to fix it, then you may wind up having to repeat the bug fix n times in the other versions that came after (because the code where the bug exists was copy/pasted).
In the refactored version with little or no repetition, if the bug were isolated in the ParseUtil.refactoredRepeatedMethod1()
, then you fix it only once there.
Upvotes: 5
Reputation: 1119
It sounds like a strategy pattern as you want to use different implementations of a Loader
class to load different XML files.
You can instantiate multiple Loader
instances with application startup one-by-one (or all at once reflectively) and store them in a factory. Then you can ask the factory to give you a Loader
based on the XML version.
If you want to use DI, you can have a Map<String, Loader>
object that simply maps the version of XML with its loader.
Upvotes: 2