Hi!
I'm writing a client server application that uses protobuf as data interchange format. Now, when my server gets an protobuf message, he choose what action it can take (depending on message type, the messages has tree structure, and basically the 'ending' leafs are actions that server can take) and then it passes this message directly to methods that handles them. Everything is working great (and in fact it is really handy to have a has_foo methods), but... I think this breaks separation of concerns design principle, and whenever I will want to change the communication protocol (e.g. to unix socket where serialization is not needed) I will have to rewrite... almost whole application.
Normally I would create an interface and an adaptor library to separate protbuf generated code (and maybe some other protocols) from the server implementation itself. Something like.
class IMessage {
virtual bool has_foo() const;
virtual int foo() const;
virtual void set_foo(int);
// my messages contains soemtimes 20 fields
}
class PbAdapter : public IMessage {
// implementation
}
class IMessage {
virtual bool has_foo() const;
virtual int foo() const;
virtual void set_foo(int);
// my messages contains soemtimes 20 fields
}
class PbAdapter : public IMessage {
// implementation
}
To copy to clipboard, switch view to plain text mode
But this is a lot of code which needs to be written, and I thought that using so big interfaces for "stupid" data structure is an overkill. Second idea was to create a structure with optional fields and then copy (or move) from it and to it.
struct Message{
boost::optional<int> foo;
}
Message adapter(pb::Message pb){
Message m;
m.foo = pb.foo();
}
struct Message{
boost::optional<int> foo;
}
Message adapter(pb::Message pb){
Message m;
m.foo = pb.foo();
}
To copy to clipboard, switch view to plain text mode
using this approach, I'll have an possibility for check if field exists ( optional::is_initialized() ) and a simple way of handling those messages. But I need to copy data from my struct to protobuf when creating a protobuf message (this is done 'automatically' when I use protobuf directly) so it's not a ideal approach either.
So the question is: Should I use an interface, or a simple structure and don't bother copying of the messages, or use the second approach with some "std::move" magic and move. Or maybe something else
And i know that premature optimizations are the root of all evil
but when there is a chance to not copy an object, why not use it? 
Question almost the same a: http://programmers.stackexchange.com...esign-patterns
Bookmarks