当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

基于策略的设计VS多继承学习

    基于策略的设计是对多继承的超越

    基于策略的设计(Policy Based Design)包含两个重要的部分:策略类(Policy-Classes)和一个具有极大张力的核心。

    许多人在看基于策略的设计的时候,往往注意到了前者(策略类),注意到了正交分析的思想,却忽视了后者(核心)。这是因为策略类的思想较为容易接收,而且已 经存在很多类似的概念。于是乎很多人认为基于策略的设计是作者在炒冷饭,是概念的炒作。还有人认为声称掌握了基于策略的设计思想,但是给出的代码却是基于 单纯的多继承。

    其实Andrei Alexandrescu在Modern C++ Design中已经明确区别了基于策略的设计和多继承之间的区别。使用多继承是无法实现基于策略的设计的!正如前面所说,基于策略的设计包含两个方面:策 略类和核心。而多继承包含什么呢?也包括两个方面:多个基类和子类的实现。下面就分别对比一下。

    策略类与多继承的基类。

    这两者比较类似,区别不是很大。但是策略类在涵盖范围上面,可以说,是超越了\"类\"的。策略类在理论上面可以是类型(包括基本类型和自定义类型)、数据和模 板。这是因为模板可以接收三种参数:数值模板参数、类型模板参数和模板模板参数。相比之下,可以用作多继承的基类的东东,只有\"类\"了。

    核心与多继承中子类的实现。

    这是两个概念的更加重大的区别,也是基于策略的设计较多继承更加优越的地方。优越的地方有二:基于策略的设计已经为用户提供了一个实现的框架;基于策略的设计可以避免滥用多继承导致的组合爆炸问题。

    实现的框架就是指前面所说的具有极大张力的核心。例如我们使用Loki::SmartPtr的时候,从来都是拿来就用,从来都没有考虑过SmartPtr的 内部实现问题。这就是因为SmartPtr已经为我们提供了一个实现框架,我们需要作的只是选择不同的策略类进行组合。几个零件,往SmartPtr上面 一安就OK了。

    如果换作多继承呢?多继承如何来处理这个问题?用户自己来实现?自己实现,费时费力,还免不了有一个bug,一点都没有体现出复用的优势,不利于软件质量的提高。

    这位看官说了,让基础库的设计者为我们提供这个实现。好,还是举SmartPtr的例子,SmartPtr的定义如下: 
    1  template
    2  <
    3  typename T;
    4  template <class> class OwnershipPolicy = RefCounted,
    5  class ConversionPolicy = DisallowConversion,
    6  template <class> class CheckingPolicy = AssertCheck,
    7  template <class> class StoragePolicy = DefaultSPStorage
    8  >
    9  class SmartPtr;

   考虑比较简单的情况,继承库的实现者们为每个Policy提供了两个个预定义的实现,那么四个Policy一组合,就意味着新产生了16个新的子类。呜乎哀哉,爆炸了。不但组合爆炸,而且还不解决问题:如果用户使用自定义的Policy,依然要自行派生新的子类。

    而基于策略的设计,为用户提供了一个使用模板实现的核心,这个核心只需要一个实现,不需要用户重复实现;而且可以接收用户自定义的Policy,拿来就用,不需要多余的代码,达到了充分的代码复用。

 

相关内容
赞助商链接