如何在c ++中透明地处理不同的协议版本? [英] How to handle different protocol versions transparently in c++?

查看:103
本文介绍了如何在c ++中透明地处理不同的协议版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个通用的C ++设计问题。



我正在编写一个使用客户端/服务器模型的应用程序。现在我正在写服务器端。许多客户已经存在(一些由我自己编写,其他由第三方编写)。问题是,这些现有的客户端都使用不同的协议版本(多年来已经有2-3个协议更改)。



因为我重新编写服务器,我认为这将是一个伟大的时间设计我的代码,使我可以处理许多不同的协议版本透明。在所有协议版本中,来自客户端的第一个通信包含协议版本,因此对于每个客户端连接,服务器确切知道需要谈话哪个协议。



  if(clientProtocolVersion = = 1)
//在这里做一些事情
else if(clientProtocolVersion == 2)
//在这里做其他事情
else if(clientProtocolVersion == 3)
//在这里做第三件事...

这个解决方案很差,原因如下:


  1. 当我添加一个新的协议版本,我必须找到源树中的所有地方,使用这些if语句,

  2. 如果有新的协议版本,并且协议版本的某些部分与另一个版本相同,我需要修改if语句,使它们读取 if(clientProtoVersion == 5 || clientProtoVersion == 6)

  3. 我确定还有更多的原因是为什么它是坏的设计,但我现在不能想到他们。 li>

我正在寻找的是一种使用C ++语言的特性来智能地处理不同协议的方法。我已经考虑过使用模板类,可能与模板参数指定协议版本,或者也许一个类heirarchy,每个不同的协议版本的一个类...



我相信这是一个非常常见的设计模式,所以许多人之前必须有这个问题。



编辑: >

你们中的许多人建议继承父母,最旧的协议版本在顶部,像这样(请原谅我的ASCII艺术):

  IProtocol 
^
|
CProtoVersion1
^
|
CProtoVersion2
^
|
CProtoVersion3

...这似乎是一个明智的事情, 。但是,当您需要扩展协议并从根本上添加新的消息类型时会发生什么?如果我在 IProtocol 中添加虚拟方法,并在 CProtocolVersion4 中实现这些新方法,协议版本?我想我的选择是:




  • 使默认实现为NO_OP(或可能在某处记录消息)。

  • 抛出异常,虽然这看起来是个坏主意,即使我在输入它。

  • ...还要做别的吗?



Edit2:



对于上述问题,协议消息需要比旧版本更多的输入吗?例如:在protocl版本1中的



,我可能有:



ByteArray getFooMessage (string param1,int param2)



在协议版本2中,我可能需要:



ByteArray getFooMessage(string param1,int param2,float param3)



不同的方法签名,这是罚款,除了它强迫我通过所有调用代码,并将所有调用与2个参数改为3个参数,这取决于使用的协议版本,这是我想在第一个



将协议版本信息与其余代码分离的最佳方法是什么,以使当前协议的详细信息对您隐藏?

解决方案

由于您需要动态选择要使用的协议,使用不同的类(而不是模板参数)为选择协议版本似乎是正确的方式去。



由于这些都是同一协议的所有不同版本,你可能可能在基类中有共同的东西,然后在子类中的差异。另一种方法可能是使基类用于协议的最旧版本,然后使每个后续版本具有从先前版本继承的类。这是一个有点不寻常的继承树,但它的好处是,它保证为更高版本做的更改不会影响旧版本。 (我假设协议的旧版本的类将很快稳定,然后很少变化。



然而,你决定组织层次结构,你会想要选择协议版本对象,一旦你知道协议版本,然后传递给你的各种需要谈协议的事情。


This is a generic C++ design question.

I'm writing an application that uses a client/server model. Right now I'm writing the server-side. Many clients already exist (some written by myself, others by third parties). The problem is that these existing clients all use different protocol versions (there have been 2-3 protocol changes over the years).

Since I'm re-writing the server, I thought it would be a great time to design my code such that I can handle many different protocol versions transparently. In all protocol versions, the very first communication from the client contains the protocol version, so for every client connection, the server knows exactly which protocol it needs to talk.

The naive method to do this is to litter the code with statements like this:

if (clientProtocolVersion == 1)
    // do something here
else if (clientProtocolVersion == 2)
    // do something else here
else if (clientProtocolVersion == 3)
    // do a third thing here...

This solution is pretty poor, for the following reasons:

  1. When I add a new protocol version, I have to find everywhere in the source tree that these if statements are used, and modify them to add the new functionality.
  2. If a new protocol version comes along, and some parts of the protocol version are the same as another version, I need to modify the if statements so they read if (clientProtoVersion == 5 || clientProtoVersion == 6).
  3. I'm sure there are more reasons why it's bad design, but I can't think of them right now.

What I'm looking for is a way to handle different protocols intelligently, using the features of the C++ langauge. I've thought about using template classes, possibly with the template parameter specifying the protocol version, or maybe a class heirarchy, one class for each different protocol version...

I'm sure this is a very common design pattern, so many many people must have had this problem before.

Edit:

Many of you have suggested an inheritance heirarchy, with the oldest protocol version at the top, like this (please excuse my ASCII art):

IProtocol
    ^
    |
CProtoVersion1
    ^
    |
CProtoVersion2
    ^
    |
CProtoVersion3

... This seems like a sensible thing to do, in terms of resuse. However, what happens when you need to extend the protocol and add fundamentally new message types? If I add virtual methods in IProtocol, and implement these new methods in CProtocolVersion4, how are these new methods treated in earlier protocol versions? I guess my options are:

  • Make the default implementation a NO_OP (or possibly log a message somewhere).
  • Throw an exception, although this seems like a bad idea, even as I'm typing it.
  • ... do something else?

Edit2:

Further to the above issues, what happens when a newer protocol message requires more input than an older version? For example:

in protocl version 1, I might have:

ByteArray getFooMessage(string param1, int param2)

And in protocol version 2 I might want:

ByteArray getFooMessage(string param1, int param2, float param3)

The two different protocol versions now have different method signatures, which is fine, except that it forces me to go through all calling code and change all calls with 2 params to 3 params, depending on the protocol version being used, which is what I'm trying to avoid in the first place!

What is the best way of separating protocol version information from the rest of your code, such that the specifics of the current protocol are hidden from you?

解决方案

Since you need to dynamically choose which protocol to use, using different classes (rather than a template parameter) for selecting the protocol version seems like the right way to go. Essentially this is Strategy Pattern, though Visitor would also be a possibility if you wanted to get really elaborate.

Since these are all different versions of the same protocol, you could probably have common stuff in the base class, and then the differences in the sub classes. Another approach might be to have the base class be for the oldest version of the protocol and then have each subsequent version have a class that inherits from the previous version. This is a somewhat unusual inheritance tree, but the nice thing about it is that it guarantees that changes made for later versions don't affect older versions. (I'm assuming the classes for older versions of the protocol will stabilize pretty quickly and then rarely ever change.

However you decide to organize the hierarchy, you'd then want to chose the protocol version object as soon as you know the protocol version, and then pass that around to your various things that need to "talk" the protocol.

这篇关于如何在c ++中透明地处理不同的协议版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆