C++设计与多态性

4
我是一名有用的助手,可以为您翻译文本。

我对C++类设计有一个通用问题。例如,我需要一个数据包生成器。因此,根据数据包的类型,我必须生成该类型的数据包。因此,我有一个基础数据包生成器类。

方法1:

class BasePacketGenerator {
public:
    virtual Packet* generatePacket (int type); // implements the generic case
                                               // hence not pure virtual
protected:
    //
    // Common functionality for all types
    // 
   virtual void massagePacket (Packet& pkt); // called by generatePacket
                                           // but needs special handling for 
                                           // some types
   virtual void calculateCheckSum(Packet& pkt); // called by generate packet
   ...
};

处理每种类型的派生类:

class Type1PacketGenerator : public BasePacketGenerator {
public:
    // Dont have to override any base class implementationa
protected:
    void calculateCheckSum(Packet& pkt) override;
};

class Type2PacketGenerator : public BasePacketGenerator {
public:
    Packet* generatePacket(int type) override;
};

在Type1生成器中,我们使用多态。但是基类调用的是派生类的功能,实现了多态性。我想知道这是否是一个好的习惯?或者需要一个中介类。

方法2:

class TypeHandler {

    virtual Packet* setupPacket();
    virtual void calculateCheckSum(Packet& pkt);
    virtual void setupFields (Packet& pkt);
}

class PacketGenerator {
public:

    TypeHandler *handler_; // lets say this is setup based on the type

    Packet* generatorPacket(int type)
    {
       auto packet = handler_->setupPacket();
       handler_->massagePacket();
       handler_->calculateCheckSum(*packet);
       return packet;
    }
}

采用哪种方法有什么优势吗?

Approach1更灵活,因为它不必遵循相同的做事方式。例如:如果Type2Generator不需要校验和,则甚至不必调用calculateCheckSum(),如果需要一些额外的功能,则不必将其添加到所有类型生成器中。

但是,Approach2更易读,因为所有类型都以相同的方式执行操作。


似乎是工厂模式? - SergeyA
1
我相信你的第二个例子涉及到策略设计模式 - https://en.wikipedia.org/wiki/Policy-based_design。它与模板很搭配。 - audio
你的问题的答案很大程度上取决于不同的因素。类设计应该考虑到域和问题的许多方面。例如,为什么你不能实现“最简单”的多态设计?[此处示例](http://coliru.stacked-crooked.com/a/98159aabcce2c8ea)。一个“packet”接口以及每个类型的不同实现。 - BiagioF
@BiagioFesta:这与我的第二种方法类似,只是它使用了一个纯接口类。我将尝试看看是否可以创建一个接口类,并将常见功能抽象到另一个类中。 - MGH
1个回答

1
现代设计理念倾向于非常强烈地分离关注点。因此,这导致了更喜欢只是纯虚函数声明的基类。
每个类都负责一件事情。
因此,你的第二种方法被认为更可取。主要原因(也是唯一需要的原因)是:它使编写适当的单元测试变得更加容易。
编辑:请注意,它仍然看起来有些笨重,但这更多是The codereview stackexchange的问题,您可以在那里获得有关结构的详细反馈。

感谢您的反馈。关于“仅仅是纯虚函数声明的基类”,我想如果我将所有通用功能移动到另一个类中,每个类型处理程序只需引用它即可实现。 - MGH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接