灵活的设计取代了switch语句

问题描述

| 我正在研究网络程序,并使用C ++设计Linux服务器。设计基本结构非常简单。我有一个包定义,其标头具有固定的大小。
typedef enum{
     PACKET_LOGIN_REQ = 1,PACKET_LOGIN_RES,PACKET_STORE_REQ,PACKET_STORE_RES
}PACKET_TYPES;

typedef struct {
     PACKET_TYPES type;
     short bodySize,long long deviceid
}HEADER;

.
.

/*more deFinitions here*/

typedef struct{
     HEADER head;
     union BODY{
          LOGIN_REQ loginReq;
          LOGIN_RES loginRes;
          .
          .
          more types
     }
}
每当我添加更多数据包类型时,我都必须修改switch语句以添加更多情况以处理新添加的数据包。 我使用的是联合类型,因此不必更改整个数据包结构。相反,我可以将新添加的数据包类型添加到联合结构中。 但是,当我尝试使用
switch
语句解析原始数据以放入数据包时,则每次都必须添加每个
switch
语句。 我认为这不是一个好的设计模式,我想知道如何以更灵活的方式设计结构。 有没有更好的方法来处理此问题(更好的设计模式)?有关的教程或参考资料呢?     

解决方法

        您应该使用类,而不是ѭ1而是使用多态调用。 那样的东西(伪鳕鱼):
class Packet{
public:
   Packet();
   virtual ~Packet();
   virtual HandleMe()=0;
protected:
   // fields 
}

PacketTypeOne: public Packet{
public:
  virtual HandleMe(); // implementation for type 1
}

PacketType2: public Packet{
public:
  virtual HandleMe(); // implementation for type 2
}

PacketTypeX: public Packet{
public:
  virtual HandleMe(); // implementation for type X
}
以及从何处获得数据包:
...
Packet* newPacket = PacketFactory::CreateNewPacket(packetTypeX); // factory will create
              // the right instance.
...
// now handle it:
newPacket->HandleMe();
...
做完了     ,        由于您的代码是C风格的,而不是C ++风格的代码,因此我将为您提供C答案。 使用函数指针。就像是:
typedef int (*ParseFunc)(const char *,len,struct MyStruct);

typedef struct PacketParser_
{
    PACKETType type;
    ParseFunc parseFunc;
} PacketParser;

const PacketParser[] parser = 
{
   { PACKET_LOGIN_REQ,LoginReqParser }
   { PACKET_LOGIN_RES,LoginResParser }
   .
   .
   .
}
然后,您遍历所有数据包类型并调用相应的函数。每当您获得新的数据包类型时,只需在
PacketParser
函数中添加另一行即可。 如果您使用的是C ++,则最好使用多态。     ,        在大多数情况下,应避免
union
s。这是其中一种情况:-) 如上所述,答案是使用多态性。将switch语句转换为多态的规范方法是使用Visitor设计模式。 虽然正常的多态性使用
virtual
方法可能会对您有所帮助,但还是有问题。
virtual
方法使您可以基于单个对象(
Packet
)调度正确的方法。但是,您还取决于要采取什么措施。例如,如果您有许多
switch
语句,而没有一个,那么
Visitor
模式将是更可取的。     ,        你可能想要 ... 用多态替换条件 本质上,您找到了一个很好的超类,并且为每个类型代码创建了一个不同的子类。 您还想购买《重构:改进现有代码的设计》的副本,Fowler,Martin(1999)/ Addison Wesley。