Is it bad practice to have the static deserialization method in the interface class as below?
class IBase
{
~IBase();
virtual void Foo()=0;
virtual const char* Serialize()=0;
static std::unique_ptr<IBase> Deserialize(const char* data); // <-- This
};
IBase will travel across DLL boundaries, so an effective method of serialization is for each object to serialize itself, hence the IBase::Serialize
function.
Then when we have raw data and we want to deserialize back to an object, it seems logical to call IBase::Deserialize
, so that the Serialize and Deserialize functions are closely coupled.
boost::serialization does some clever automatic stuff so that the Deserialize factory function just looks like data >> pIBase;
, so there's no manually updating the factory function for new derived types.
The alternative as I see it is to create an IBaseDeserializer class to hold the Deserialize function:
class IBase
{
~IBase();
virtual void Foo()=0;
virtual const char* Serialize()=0;
};
class IBaseDeserializer
{
static std::unique_ptr<IBase> Deserialize(const char* data);
};
Most of the similar questions on SO claim that the first method should be avoided because it violates Single Responsibility Principle, having the base interface also be a factory. However, I feel as though this is a special case in the sense that it's a corresponding function to the base interface's Serialize function, which just happens to be a factory. However, it doesn't make a lot of sense for a derived object to have a Deserialize function, or for an interface to have an implementation, albeit static.
After writing this I'm leaning more towards the second method, but I still see value in the first. What's best practice here? What other pro's and con's are there, or am I way off base (no pun intended) altogether and should be doing something else?