摘要:
在基类中进行修改代码高昂:请将公用函数设为非虚拟的。应该将虚拟函数设为私有的,或者如果派生类需要调用基类版本,则设为保护的。
在面向对象层次结构中进行修改是昂贵的,所以应该实施完整的抽象:将公用函数设为非虚拟的,将虚拟函数设为私有的。这就是所谓的非虚拟接口模式。
公用虚拟函数本质上有两种不同而且互相竞争的职责,针对的是两种不同而且互相竞争的目标:
1.它制定了接口。作为公用函数,它是类向外界提供的接口的一部分。
2.它制定了实现细节。作为虚拟函数,它为派生类替换函数的基类实现提供了一个钩子,它是一个自定义点。
因为这两种职责的动机和目标都不同,所以它们可能会发生冲突,因而从定义上来讲一个函数无法很好地履行两种职责。公用虚拟函数本身有两种on革命性不同的职责和两种互相竞争的目标,这是没有很好地将问题关注点分离的标志。
通过将公用函数与虚拟函数分离,可以获得如下明显的好处。
1.每个接口都能自然成形。将公用函数与自定义接口分离后,每个接口都能很容易地获得符合其自然需求的形式,而不用寻找折中方案,以使他们看上去相同。两个接口经常需要不同数量的函数或不同的参数。
2.基类拥有控制权。基类现在完全控制着其接口和策略,可以实时接口的前后置条件、插入度良性代码,还可以在一个方便的可重用场所中做任何类似的工作。因此,这种为了分离而进行的“预构“能够促进良好的类设计。
3.基类能够健壮地适应变化。以后,我们可以随意改变构思、添加前后条件检查,或者将处理工作分成更多步骤,或者进行重构,或者用Pimpl惯用法实现更完整的接口与实现的分离,或者对基类的可自定义性进行其他修改,而不会影响到使用此类或者从此类继承的任何代码。