C++类设计与多态:两种报文生成器实现方案的选型疑问
嘿,针对你提出的这两个C++报文生成器方案,我来帮你拆解分析一下,看看哪种更适合你的场景,顺便解答你关于方案1的设计疑问~
方案1:模板方法模式的典型应用
先回答你最关心的问题:Type1生成器这种基类调用派生类重写方法的方式,完全是模板方法模式的标准惯用法,这是非常成熟且合理的设计,不需要额外引入中间类。
模板方法模式的核心就是基类定义一套通用的算法骨架(比如这里的generatePacket),把可变的步骤延迟到派生类中实现。你的方案1完美贴合这个思路:
- 基类
BasePacketGenerator实现了报文生成的通用流程,调用massagePacket、calculateCheckSum等可定制步骤 - 派生类只需要重写自己需要定制的步骤(比如Type1重写校验和计算,Type2重写整个生成逻辑)
方案1的优势
- 极致灵活性:像你说的,Type2可以直接重写
generatePacket跳过校验和调用,甚至完全自定义生成流程;新增通用功能时,只需要在基类加新的虚函数,派生类按需重写即可,不需要修改所有类型的生成器 - 代码复用率高:通用逻辑都放在基类,派生类只需要关注差异化部分
方案1的潜在风险
- 如果派生类随意重写
generatePacket,可能会破坏基类定义的通用流程,导致不同类型报文的生成逻辑不一致,后期维护成本上升 - 当派生类数量较多时,基类的虚函数可能会越来越多,类的职责会逐渐膨胀
方案2:策略模式的实践
方案2采用的是策略模式,把不同类型报文的处理逻辑封装到TypeHandler策略类中,PacketGenerator作为上下文,固定了生成报文的流程(setup → massage → calculate checksum)。
方案2的优势
- 流程一致性强:所有类型的报文生成都遵循统一的步骤,可读性和可维护性更高,不会出现某个派生类私自修改流程的情况
- 职责划分清晰:
PacketGenerator只负责调度流程,TypeHandler专注于具体类型的报文处理,符合单一职责原则 - 扩展性好:新增报文类型只需要新增对应的
TypeHandler子类,不需要修改现有代码
方案2的劣势
- 灵活性不足:如果某个类型需要跳过某个步骤(比如不需要校验和),只能在对应的
TypeHandler中做空实现,或者修改PacketGenerator的流程逻辑,不如方案1直接重写generatePacket来得直接 - 每个
TypeHandler都需要实现所有虚函数,即使有些步骤是通用的,可能会存在代码冗余(可以通过给TypeHandler加一个基类实现通用逻辑来缓解)
选型建议
- 如果你的场景中,大部分报文的生成流程是统一的,只有少数步骤需要定制,或者未来可能需要支持一些特殊流程的报文类型,优先选方案1
- 如果你的场景要求所有报文必须严格遵循统一的生成流程,不允许随意修改步骤,或者希望团队成员更容易理解和维护代码,优先选方案2
另外,如果你想兼顾两者的优点,可以考虑在方案2的基础上,给TypeHandler加一个抽象基类实现通用步骤,让子类只重写需要定制的部分,这样既保证了流程一致性,又有一定的灵活性。
内容的提问来源于stack exchange,提问作者MGH
相关产品推荐
相关产品推荐

