2

I'm tasked with changing some procedural Java code into Object Oriented re-usable module. It's an XML generator utility which uses velocity for XML generation. There are also business rule enrichments, all of which is configurable in Database tables. I have already removed huge if-else statements for rules and made them into Rule Objects with Abstract classes and interfaces which other Applications can extend and implement. However I'm facing difficulty with re-designing the overall class - XMLGeneratorUtil, which takes a JDBC connection , Logger and Properties in its constructor and does a hell lot of things in the constructor like building different Data structures(containing static data) from database.

Now, I know its not good to connect to Database from Constructor, but if I change to some thing like below:

XMlGeneratorUtil xmlUtil = new XMLGeneratorUtil();
xmlUtil.initialize(Conenriches conn, Properties prop , Logger logger) // Do DB Connections and all initializations here
xmlUtil.generateXML(data); // Data is a HashMap containing busines data that goes into the XML
  1. How can I be sure that the users of my utility call initialize before they call generateXML? Should I create some Wrapper that internally creates a lightweight object and then initializes it without the user knowing it?

  2. Also , is it good for my re-usable library to accept Connection as a parameter? Idea is that the calling Application of my utility may choose to manage their own Connection , so they just pass it to my API

  3. Against the SRP (Single Responsibility principle) the XMLGeneratorUtil manipulates business data(which ultimately goes into XML data) as well as generates XML. Should the data enrichment be exposed as different API? (And then the user calls XMLGeneratorUtil)

1

Answers to your points:

How can I be sure that the users of my utility call initialize before they call generateXML? Should I create some Wrapper that internally creates a lightweight object and then initializes it without the user knowing it?

No. That would essentially be the same thing as invoking the database from your constructor. Instead, make generateXML throw an exception if the object is in the wrong state (eg, initialize hasnt' been called).

Also , is it good for my re-usable library to accept Connection as a parameter? Idea is that the calling Application of my utility may choose to manage their own Connection , so they just pass it to my API

Probably not. Consider injecting something a bit less low-level. Surely the Rules Object's dependency isn't the entire database, but simply a subset of its data. Could that subset be represented as a Repository? In other words, if your Rules Object requires pulling rules from the database, don't hand it a dbConnection, hand it a RulesRepository.

I can't answer the third question because I'm not sure what you mean by "enriches business data."


But, at a high level, the answer to this question is:

Rethink your object dependencies. Injecting a database connection is very broad and allows your Rules Object to do far more with your data that it should be able to.

Consider injecting classes that only expose what is needed from the database. Using a Repository will help you do this and will also decouple you from the data persistence medium. So, in the unlikely event you ditch databases and move to another storage medium, you'll only need to update your Repositories and not all their consumers.

  • My RuleObjects have business logic in them, and they expect the data that they manipulate in a HashMap which in turn I populate from DB. Applications can implement their own Rule Objects. But the RuleObject data population is happening in the constructor of XMLUtility and applying rules is currently happening inside generateXML method which seems against SRP – Plaiska Apr 26 '14 at 13:27
  • Also to add, the xmlUtility does not depend on the rule object enrichment though it does requires data from database. But thinking it may be clumsy to ask users to call DataEnricher.enrich and then do XMLUtility.generateXML though the former is of no use without the latter – Plaiska Apr 26 '14 at 13:39
0

Why not make the whole constructor-building into a class and pass only that class into the constructor? Then you can even abstract it as interface, so the XML generation doesn't even depend on DB and can accept any data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.