I'm working on a C++ communication library in which I receive serialized data from a number of devices (network sockets, uart/usb, CAN, and LIN networks). I also need to create serialized data from my message objects.
I have a base class called MessageBase from which I presently have two derived classes called Message and CtrlMessage. The project will eventually need a few more message types in the future and so I'm looking to implement using a design pattern that allows easy to expand to new message types in the future.
My other goal is, as Scott Meyes puts it, hard to use the classes incorrectly and easy to use correctly.
I began looking at using NVI pattern and using C++ factory to create messages however, the Factory class would then need to handle some of the de-serialization of a header in order to figure out what Type of message is in the payload.
class MessageBase
{
private:
// other public & private methods omitted for brevity
MessageBase &ISerialize( dsStream<byte> &sdata) = 0;
public:
MessageBase &Serialize( dsStream<byte> &sdata)
{
ISerialize(sdata);
}
}
class Message : public MessageBase
{
private:
// other public & private methods omitted for brevity
MessageBase &ISerialize( dsStream<byte> &sdata);
public:
}
class MessageFactory
{
private:
public:
CreateMessageFromStream( dsStream<byte> &RxData)
{
// read N bytes from RxData to determine type and then
// jump into switch to build message
switch(MsgType)
{
case MSG_DATA:
{
Message *pMsg = new Message(RxData);
}
break;
case MSG_CTRL:
{
MessageCtrl *pMsg = new MessageCtrl(RxData);
}
break;
}
}
// I shorten quite a bit of this to, hopefully, give the basic idea.
The other approach I've been studying is the Double Dispatch as outlined by Scott Meyers Item#33 in his More Effective C++ book. But that only appears to shift the problem to either requiring all the sibling derived classes to know about each other or the more advanced solution with stl map to emulate vtable. That code looks awful and hard to follow.
I took a look at the C++ visitor pattern and the Builder Creational pattern and these all require the caller to know what kind of derived Message type you want to instantiate ahead of time.
I know I could just put a big switch statement in the MessageFactory, like shown, and be done with it but what I'm after is a way to add new message types derived from MessageBase and not have to touch the MessageFactory class. I don't want other programmers to have to know or go find all the places where code needs to be updated for a new message type.
Also, this is an embedded application and that being the case certain things are off the table. I can use Template programming techniques but I do not have any STL library nor do I have any Boost library support.
Any suggestions?