Tho*_*omi 7 c++ language-agnostic design-patterns protocols
这是一个通用的C++设计问题.
我正在编写一个使用客户端/服务器模型的应用程序.现在我正在编写服务器端.许多客户已经存在(一些由我自己编写,另一些由第三方编写).问题是这些现有客户端都使用不同的协议版本(多年来已经有2-3次协议更改).
由于我正在重写服务器,我认为现在是设计我的代码的好时机,这样我就可以透明地处理许多不同的协议版本.在所有协议版本中,来自客户端的第一个通信包含协议版本,因此对于每个客户端连接,服务器确切地知道它需要谈论哪个协议.
执行此操作的天真方法是使用以下语句来丢弃代码:
if (clientProtocolVersion == 1)
// do something here
else if (clientProtocolVersion == 2)
// do something else here
else if (clientProtocolVersion == 3)
// do a third thing here...
Run Code Online (Sandbox Code Playgroud)
由于以下原因,此解决方案非常糟糕:
if (clientProtoVersion == 5 || clientProtoVersion == 6).我正在寻找的是一种使用C++语言的功能智能地处理不同协议的方法.我考虑过使用模板类,可能使用指定协议版本的模板参数,或者可能是类heirarchy,每个不同的协议版本都有一个类...
我敢肯定这是一种非常常见的设计模式,所以很多人以前都遇到过这个问题.
编辑:
你们中的许多人已经建议继承heirarchy,最旧的协议版本在顶部,像这样(请原谅我的ASCII艺术):
IProtocol
^
|
CProtoVersion1
^
|
CProtoVersion2
^
|
CProtoVersion3
Run Code Online (Sandbox Code Playgroud)
......就重复使用而言,这似乎是一件明智的事情.但是,当您需要扩展协议并添加基本的新消息类型时会发生什么?如果我在其中添加虚拟方法IProtocol并实现这些新方法CProtocolVersion4,那么在早期协议版本中如何处理这些新方法?我想我的选择是:
EDIT2:
除了上述问题,当较新的协议消息需要比旧版本更多的输入时会发生什么?例如:
在protocl版本1中,我可能有:
ByteArray getFooMessage(string param1, int param2)
在协议版本2中,我可能想要:
ByteArray getFooMessage(string param1, int param2, float param3)
两个不同的协议版本现在有不同的方法签名,这很好,除了它迫使我通过所有调用代码并将所有调用更改为2个参数到3个参数,具体取决于所使用的协议版本,这就是我所说的我试图避免在第一位!
将协议版本信息与其余代码分离的最佳方法是什么,以便隐藏当前协议的具体内容?
Lau*_*ves 10
由于您需要动态选择要使用的协议,因此使用不同的类(而不是模板参数)来选择协议版本似乎是正确的方法.基本上这是战略模式,虽然如果你想要真正详细,访客也是可能的.
由于这些都是同一协议的不同版本,因此您可能在基类中有共同的东西,然后是子类的差异.另一种方法可能是使基类用于最旧版本的协议,然后让每个后续版本都具有继承自先前版本的类.这是一个有点不寻常的继承树,但它的好处是它保证为更高版本所做的更改不会影响旧版本.(我假设旧协议版本的类会很快稳定下来,然后很少会改变.
但是,如果您决定组织层次结构,则需要在知道协议版本后立即选择协议版本对象,然后将其传递给需要"协商"协议的各种事物.