如何在C ++中管理并行,依赖继承?

时间:2013-10-16 19:38:49

标签: c++ design-patterns

我正在尝试解决C ++中涉及并行继承的问题。我发现的最近的问题是Parallel inheritance trees, where classes from one tree have containers of classes from another,但它并没有完全回答我的问题。

我有一个由三个类组成的模型:Model,Trainer,InstanceProcessor(IP),它们分别包含模型数据,训练函数和模型处理代码。现在我有大约10个不同版本的这个模型,有很多代码重叠但有些差异,创建了某种形式的并行继承:

Model - ModelA, ModelB, ModelC, ...
Trainer - TrainerA, TrainerB, TrainerC
IP - IPA, IPB, IPC

在代码的主体中,我使用Model *指针根据解析的参数访问特定的模型。

Model和Trainer都需要多个短暂的IP实例,Model还需要一个Trainer的永久实例。

我当前的实现使用三个基类和一些虚函数,然后模拟从这些基类继承的特定类。这需要我使用大量的铸件(例如,从model.h中的Trainer *培训师到TrainerA,以满足特定需求)。

我怀疑有一种更优雅的方式来实现这个(使用模板/接口?),并且想知道是否有人能指出我正确的方向?谢谢!


编辑:为了澄清以下答案中的一点,其中一个复杂因素在于我想要的事实。 Trainer类具有函数basic_train():

Trainer::basicTraining() {
    ...
    IP* ip = new IP(some args);
    ip->doStuff();
    ...
}

现在根据所使用的培训师类型创建适当的IP。该函数的其余部分不会从TrainerA更改为TrainerB实例。

3 个答案:

答案 0 :(得分:2)

当两个单独的层次结构的成员紧密耦合时,继承不会给你带来太大的影响。应该可以使用混合匹配策略的继承promises(即ModelA使用TrainerBIPC),而实际上这不起作用。

然而,要实现的一个非常重要的事情是,彼此呈现的模型,培训师和IP的界面可能与它们共同呈现给主应用程序的界面不同:主应用程序将它们视为组统一对象,而模型/培训师/ IP的每个子组(即ABC组)将同一组的成员视为高度专业化。因此,虽然继承可能对继承层次结构的各个部分不利,但它可能对您的主程序有利。

这将引导您使用abstract factory模式的可行解决方案。主应用程序有一个“工厂工厂”,可以根据传入的内容为其提供FactoryAFactoryBFactoryC。每个FactoryX生成{{1} }},ModelXTrainerX个对象,将它们作为公共超类(即IPXModelTrainer)呈现给您的主程序。< / p>

然而,在工厂的胆量中,实施对象是在了解“对应物”的确切类型的基础上创建的。例如,当IP配置了ModelA时,它不会使用Trainer类型的对象 - 它会获得Trainer。由于TrainerA知道它创建的对象之间的依赖关系,因此提供正确类型的对象没有问题。与此同时,主程序并不知道这种专业化,而且(FactoryAModelATrainerA)部分对概括性几乎一无所知。

答案 1 :(得分:1)

基本上播放很糟糕,因为它很脆弱(你应该忘记在你应该的时候更新代码)。相反,你应该利用多态性。我想你可能想看一下visitor pattern,这可能与你最初使用接口的想法相符。

答案 2 :(得分:0)

用更抽象的术语来表示:你有一组已经针对继承而修复的类,并且你希望根据用例使每个类的行为都不同。

在这种情况下,大多数情况下依赖注入策略会有所帮助:您可以为每个方法调用执行此操作,或者您可以在对象是创建。

在第一种情况下,你传入 - 作为参数 - 改变方法行为的东西(见下文)。

在第二种情况下,您将该参数传递给构造函数,并且对象必须存储该“某事”。

'something'可以像一组固定的值(例如enum)一样简单,也可以是callback / functor / lambda或object。选择任何舒适的东西,重点是它可以改变对象的行为,即使它们都是同一个类。