I am developing a library for an existing (network) protocol that frequently changes. I want to develop the library to be compatible with the current protocol and support future changes, while maintaining backwards compatibility.
Right now, my concern is about the protocol model. I'm trying to find the best way to model the protocol in C++ code.
Just so we have something to visualize, I'll present an example protocol:
MESSAGE => RESPONSE
<!.!> is the delimiter
<!.!><!.!><!.!> is the end of message
HELLO<!!>USERNAME<!.!>PASSWORD<!.!><!.!><!.!> => HELLO //Authentication succeeded
GET<!!>TIME_OF_DAY<!.!><!.!><!.!> => 14:44:25 //Get current time
GET<!!>FILE_LIST<!.!><!.!><!.!> => test.txt<!.!>test2.txt<!.!>test3.txt<!.!><!.!><!.!>
Now let's declare functions that send a message and return the result.
string sendHello(string username, string password); string sendGetTimeOfDay(); vector<string> sendGetFileList(); void sendEnd();
Now let's suppose the parameters of the message and response can change at any time for the next version of the protocol. So the parameters and/or return types may change from version to version.
The goal of the library is to make it easy to develop client applications without concern for the protocol specification and implementation.
We can expect the protocol to continue to change many times creating many versions of the implementation. The changes from version to version can be anticipated to be minor and few but the differences will add up over the course of many revisions. My initial reaction is to create a model for the current version. Upon changes, I suggest to copy the entire current model code, make the minor changes and thus have a nearly duplicate model. It seems to me to be easily maintainable and easy for the client to choose which model to use depending on the version it requires.
I should probably freshen up on the language semantics and good practices but I initially thought using templates could be effective in this design. Clients using the library could do something like this:
Protocol<1> versionOne; if (versionOne.sendHello("user","pass") == "HELLO") ...
Protocol<10> versionTen; if (versionTen.sendHello("user","pass") == "HELLO") ...
The final code certainly would be much different but I think this shows the premise. I can see problems with this approach and could suggest other options but I want to hear what you think.
Ideally, the updated library could be plugged into client code and support revisions without any or at least very minor changes.
What do you think of this approach? Is this good design considering the problem? How would you implement the Protocol class as a template? What other approaches might you consider?
Yes, this post is way too long.
P.S. This is my first post; I hope this type of post is welcome here.