- 适配器是一种非常通用的模式,它修改一个类、函数(或在C++中的模板)的接口,使其能够在需要不同接口但具有相似底层行为的上下文中使用。
- 装饰器模式是一种更窄的模式;通过添加或移除行为来修改现有接口,但不会将一个接口转换为一个完全不同的接口。
- 在经典的面向对象编程实现中,装饰的类和装饰器类都从一个共同的基类继承。这有两个限制:最重要的一个是装饰对象保留了装饰类的多态行为,但无法保留仅在具体(派生)装饰类中添加在基类中不存在的接口。第二个限制是装饰器特定于某个特定的继承层次。我们可以使用C++的泛型编程工具来消除这两个限制。
- 一般来说,装饰器会尽可能多地保留装饰类的接口,行为未修改的函数都保持不变,所以通常使用公有继承。如果装饰器必须显式地将大部分调用转发给装饰类,则继承的重要性降低,此时可以使用组合或私有继承。
- 与装饰器不同,适配器通常呈现与原始类非常不同的接口。这种情况下,通常更倾向于使用组合。例外是编译时适配器,修改模板参数,但除此之外本质上是相同的类模板(类似于模板别名)。这些适配器必须使用公有继承。
- 主要限制是它不能应用于模板函数,也不能用于将函数参数替换为包含这些参数的表达式。
- 模板别名在函数模板实例化时的参数类型,推导过程中永远不会考虑。适配器模式和策略模式都可以用来添加或修改类的公共接口。
- 适配器很容易堆叠(组合)起来,一次一个函数地构建复杂的接口。未启用的功能完全不需要特殊处理;如果未使用相应的适配器,则该功能就不会启用。传统的策略模式要求,为每个模式预先确定插槽。除了最后一个显式指定之后的默认参数外,所有策略(即使是默认的)都必须显式指定。另一方面,堆叠中间的适配器无法访问对象的最终类型,这使得实现变得复杂。而基于策略的类始终是最终类型,通过使用CRTP,这个类型可以传播到需要它的策略中。