我的团队编写了几个通过纯虚拟回调实现事件处理的 C++ 类——例如,当从另一个进程接收到消息时,处理 IPC 消息传递的基类调用它自己的纯虚函数,派生类处理事件覆盖该功能。基类知道事件已经发生;派生类知道如何处理它。
我现在想将这些基类提供的功能组合到更高级别的类中,例如,当消息从另一个进程到达时,我的新类可以使用类似的事件驱动网络类通过其网络连接转发它. 看起来我有两个选择:
(1) 组合:从每个事件处理基类派生类,并将这些派生类的对象作为成员添加到我的新类中,或者:
(2) 多重继承:使我的新类成为所有事件处理基类的派生类。
我已经尝试过(1)和(2),但我对我的实现都不满意。
还有一个额外的复杂性:一些基类是使用初始化和关闭方法而不是使用构造函数和析构函数编写的,当然这些方法在每个类中具有相同的名称。所以多重继承会导致函数名不明确。可以通过using
声明和/或显式范围解决,但不是我见过的最易于维护的东西。
即使没有这个问题,使用多重继承并覆盖几个基类中的每一个的每个纯虚函数都会使我的新类变得非常大,接近“上帝对象”。随着需求的变化(阅读:“随着需求的增加”),这不会很好地扩展。
另一方面,使用单独的派生类并将它们添加为我的新类的成员意味着我必须在每个派生类上编写大量方法以在它们之间交换信息。这感觉很像“getter and setter”——没有那么糟糕,但是有很多“从那个类中获取这些信息并将其交给这个类”,这给人一种效率低下的感觉——很多额外的方法,很多额外的读取和写入,并且类必须对彼此的逻辑了解很多,这感觉不对。我认为一个成熟的发布和订阅模型将是矫枉过正,但我还没有找到一个简单的替代方案。
如果我使用组合,也会有很多重复的数据。例如,如果我的班级的状态取决于其网络连接是否已启动并正在运行,那么我必须在受此影响的每个班级中都有一个状态标志,或者让每个班级在每次需要做出决定时都向网络班级查询其状态做出来。如果我只有一个多重继承类,我可以只使用我类中的任何代码都可以访问的标志。
那么,多重继承、组合,或者完全是别的什么?是否有关于如何最好地处理这种事情的一般经验法则?