for In the project I am working on we send messages about widgets over message queues, serializing them onto the queues as XML. The XML schema contains tags for properties that are common to all types of these widget messages, such as the widget type, command name and destination. It can also contain an arbitrarily sized list of key-value pairs to allow storage of properties that are only relevant for a specific type of widget message. The
WidgetMessage class encapsulates this data and the
WidgetMessageXmlReader classes provide serialization to and from the XML.
I have made some classes that encapsulate specific messages, for example a
FooPlaySoundMessage for a 'Foo' widget or a
BarSetLightPatternMessage for a 'Bar' widget. They each have a
ToWidgetMessage instance method and a
FromWidgetMessage static method for converting to and from the
WidgetMessage class. Each family of messages inherits from an abstract class for that widget type, e.g.
BarMessage, which in turn inherits from the
WidgetMessageMapping class; this stores the common message properties and the protected methods used by subclasses for conversion. None of these classes inherit from
WidgetMessage since I don't want them to inherit its key-value collection property and associated methods, hence the need for conversion rather than simple casting.
I like the simplicity of my API (e.g.
FooPlaySoundMessage msg = FooPlaySoundMessage.fromWidgetMessage(widgetMessage)), but the fact I am having to use protected methods in a base class to share functionality, and static methods to expose it, makes me wonder if there ought to be a separate class or two involved here (similar to
WidgetMessageXmlReader). On the other hand, I thought that part of the point of OOP is to group data and methods together and so avoid "dumb data objects".
So, do I have the right idea by adding conversion methods to my data objects, or should that functionality be extracted out into another class?
I think that in all the detail above of my current attempt at a design I didn't explain clearly enough the problem I am trying to solve.
In summary, I have a "generic" DTO class that has some strongly typed properties and a collection of key-value pairs to store other custom data. I want to have some specialized DTO classes for each set of custom data that store all the same data as the generic DTO, except with the key-value pairs replaced by strongly-typed properties. What is the best design for converting between these two types of DTO?