views:

157

answers:

3

Hello:

I've currently completed one of two phases of a project that required I write database information to XML using C++. While use of a third party tool was used to do the actually formatting of XML tags and data, I still had to design a model along with business logic to take the database tables and map them into XML structures.

For this I ended up creating an individual class for each XML structure, resulting in a large amount of classes (~75). Each class had the knowledge of how to read its associated table and serialize itself to XML through the third party tool. In the end the system worked very well ( on time and budget ) and output errors were extremely easy to find.

Phase two is almost identical however instead of formatted text it will be binary data. So while I am still considering utilizing the same strategy used in phase one, I would like to inquire, is a better method or design pattern that would lend itself to this problem? Particularly, due to the large amount of dependancies in some of the XML classes in phase one, unit testing was very difficult.

+2  A: 

Build an Generator -- if possible -- that automates the generation of the classes.

The generator of course could be fed by a specification language that specifies how the data is stored on the database.

This involves thinking about how the data could be stored as uniformly as possible.

Better still (in the sense of development efficiency -- not in the sense of education / pattern learning): Use a Generator that already exists (Open Source or Commercial one).

Edit: There are several libraries/frameworks out there that should do exactly such jobs. You use a library yet, as much I read -- but it seams that it does not do to much. There are persistency layers/frameworks to write OO data from/to datase. XML data is nothing else as object oriented representation. It might be, that you have write a layer to reach the full target, but using a third party product could be beneficial (in many cases).

Juergen
+7  A: 

You are describing a classic application of the Visitor pattern. You need for two purposes to traverse your object model, one time outputting XML, the other time binary data. It's well explained in the gang of four's book.

Each element of your model has to accept a visitor of a recognised type (typically IVisitor), and it then calls a method called, typically, AcceptVisitor on this visitor. This is the method that translates the object into XML, binary data, printable format or whatever. It may also then direct the visitor to child objects and so on. Then you write an XmlVisitor that implements IVisitor, and "visit" your structure with it - the result is XML. Similary, you can "visit" with a BinaryVisitor and get your binary output.

David M
I never complain about getting -1s, but it's good to know why if there's something wrong with the answer... would someone like to elaborate?
David M
Great answer David, however in this case I am unable to reuse the original ~75 classes used in phase one as the data structures in phase two are slightly different. I am going to keep your suggestion for further use if I need to change phase one's output format.
Matthew
Hi David, visitor pattern is a great idea, but at least it does not help for the problem of reading the data from a SQL database. In this case, this is not a "classic application". I don't see, if the OP really understands his problem, since he writes as if XML would be his internal representation. In such a case, it would be good to first get his internal representation right, instead of thinking about a visitor pattern (I would foresee not a better implementation, but it could be even worse ...)
Juergen
+1  A: 

An other idea, that might also fit:

When performance is not an issue, also generic data containers could be used. A generic data container could take a specification of one node (like an XML node or an object or even a table entry) and just store such a container.

This way, the ~75 classes could be replaced by one or a handful. Services like serialization could also be provided in a generic fashion.

Different instances could thus play the role that still now is played by different classes.

As much I understood, the data primitives used are rather straight forward and limited. So this could be implemented rather simple.

Juergen
I think you nailed it on the head with this answer Juergen, thanks.
Matthew