【发布时间】:2020-08-24 17:15:54
【问题描述】:
我正在尝试实现一个库,其中 Class1 提供了大约五个公共方法 Method1 到 Method5。 Class2 提供了两种方法——Methods6 和 Method7。 Class3 提供了一种方法——Method8。现在,对于最终用户,我想从这些类的组合中公开方法。例如。如果最终用户实例化一个名为 Class1Class2 的类,他们应该有权访问 Method1 到 Method7,如果他们实例化一个名为 Class1Class3 的类,他们应该有权访问 Method1 到 Method5 和 Method8。
我能想到 3 种不同的方法(也请提出其他方法):
多重继承:保持 Class1、Class2 和 Class3 原样。然后,创建一个从 Class1 和 Class2 公开多重继承的新类 Class1Class2。同样,我可以创建一个类 Class1Class3,它公开多个继承自 Class1 和 Class3。
多级继承:我可以从 Class1 派生 Class2,并将其称为 Class1Class2。和 Class1 中的 Class3 并称之为 Class1Class3。如果我们需要 Class1Class2Class3,我们从 Class2 和 Class3 继承该类,它们都派生自 Class1。在这里,我们将使用虚拟继承来解决菱形问题。我不希望使用 Class2Class3,所以这应该不是问题。
组成:保持 Class1、Class2 和 Class3 的原样。创建实现 Method1 到 Method7 的每个方法的 Class1Class2,并在内部将它们相应地委托给 Class1 和 Class2 的对象。类似地,Class1Class3 将组成 Class1 和 Class3 的对象。使用这种方法,我们需要为所有方法提供实现并将它们委托给组合对象。
虽然“组合优于继承”指南通常非常适合类的松散耦合等,但在上述情况下,我们必须从单独的具体实现中进行代码重用,方法 1 或 2 似乎是更好的选择。
【问题讨论】:
-
你看过 Liscov 替换原则吗?与遵守可替换性相比,正确的继承与代码重用的关系要小得多。
-
方法 1 看起来更可行。去吧。
-
@StephenNewell 是的,但是在这种情况下,对于选项 (2),从 Class1 派生的 Class2 不会改变 Class1 的任何方法,因此在技术上是 IS-A Class1。所以本质上,只要用户用 Class2 代替 Class1,什么都不会破坏。这不满足 LSP 吗?
-
如果函数采用
Class1,是否可以安全地传递Class1Class2、Class1Class3或Class1Class2Class3对于该函数执行的任何操作。如果是这样,就满足了LSP,这就是继承的合适使用。 -
另外两个需要考虑的想法:静态多态性和 CRTP。
标签: c++ oop design-patterns