Adapter 适配器模式:将一个类的接口转换成客户希望的另一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。Adapter 模式也称为包装器 Wrapper。
Adapter 模式适用于:1)你想使用一个已经存在的类,而它的接口不符合你的需求。2)你想创建一个可以复用的类,该类可以与其它不相关的类或不可预见的类(跟那些接口可能不一定兼容的类)协同工作。3)(仅适用一对象 Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
Adapter 的通用结构如下:1)类适配器;2)对象适配器;
1):类适配器,使用多重继承对一个接口与另一个接口进行匹配。
注:使用 C++ 实现适配器类时,Adapter 类应该采用公共方式继承类 Target 类,并且用私有方式继承 Adaptee 类。因此,Adater 类应该是 Target 的子类型,但不是 Adaptee 的子类型。
2):对象适配器,使用对象组合:
对象适配器采用采用对象组合的方法将具有不同的类组合在一起。该方法中,适配器 Adapter 维护一个指向 Adaptee 的指针。
Adapter 最常见的用途就是保持多态性它经常被用来保持其他设计模式所需要的多态。
1):类适配器示例代码
1: //AdapterClass.h
2: //类适配器示例
3: #pragma once
4: #include <iostream>
5:
6: //Target
7: class TargetClass
8: {
9: public:
10: TargetClass(){ };
11: virtual ~TargetClass() { };
12: virtual void Request(){
13: std::cout<<"TargetClass::Request"<<std::endl;
14: }
15: };
16:
17: //Adaptee
18: class AdapteeClass
19: {
20: public:
21: AdapteeClass() { };
22: ~AdapteeClass(){ };
23: void SpecificRequest(){
24: std::cout<<"AdapteeClass::SpecificRequest"<<std::endl;
25: }
26: };
27:
28: //Adapter: 公共继承 Target,私有继承 Adaptee
29: class AdapterClass : public TargetClass, private AdapteeClass
30: {
31: public:
32: AdapterClass(){ };
33: ~AdapterClass(){ };
34:
35: //
36: void Request(){
37: this->SpecificRequest();
38: }
39: };
2):对象适配器示例
1: //AdapterObject.h
2: //对象适配器示例
3: #pragma once
4: #include <iostream>
5:
6: //Target
7: class TargetObject
8: {
9: public:
10: TargetObject(){ };
11: virtual ~TargetObject() { };
12: virtual void Request(){
13: std::cout<<"TargetObject::Request"<<std::endl;
14: }
15: };
16:
17: //Adaptee
18: class AdapteeObject
19: {
20: public:
21: AdapteeObject() { };
22: ~AdapteeObject(){ };
23: void SpecificRequest(){
24: std::cout<<"AdapteeObject::SpecificRequest"<<std::endl;
25: }
26: };
27:
28: //Adapter
29: class AdapterObject : public TargetObject
30: {
31: public:
32: AdapterObject(AdapteeObject* adaptee)
33: : _adeObject(adaptee)
34: { }
35: ~AdapterObject(void){ }
36:
37: //
38: virtual void Request(){
39: _adeObject->SpecificRequest();
40: }
41:
42: private:
43: AdapteeObject* _adeObject;
44: };
//test
1: //test.cpp
2: #include "AdapterClass.h"
3: #include "AdapterObject.h"
4: #include <iostream>
5: using namespace std;
6:
7: int main()
8: {
9: // test for AdapterClass
10: // 注:客户所要使用的接口是 Target
11: TargetClass* targetClass = new AdapterClass;
12: targetClass->Request();
13:
14: // test for AdapterObject
15: // 注:客户所要使用的接口是 Target
16: AdapteeObject* adapteeObject = new AdapteeObject;
17: TargetObject* targetObject = new AdapterObject(adapteeObject);
18: targetObject->Request();
19:
20: delete targetClass;
21: delete adapteeObject;
22: delete targetObject;
23:
24: return EXIT_SUCCESS;
25: }
Thinking in C++ Volume 2 中给出了一个比较有意思的例子,给出了迭代器的简单实现,而且用 STL 中的标准算法进行了一些简单测试,可以参考一下:
1: // FibonacciGenerator.h
2: #pragma once
3:
4: //
5: class FibonacciGenerator
6: {
7: private:
8: int n;
9: int val[2];
10: public:
11: FibonacciGenerator() : n(0){
12: val[0] = val[1] = 0;
13: }
14:
15: // 仿函数
16: int operator()(){
17: int result = n > 2 ? val[0] + val[1] : n > 0 ? 1 : 0;
18: ++n;
19: val[0] = val[1];
20: val[1] = result;
21: return result;
22: }
23:
24: //
25: int count(){
26: return n;
27: }
28: };
//Adapter
1: // FibonacciAdapter.h
2:
3: #include "FibonacciGenerator.h"
4: #include <numeric>
5:
6: // Adapter 适配器模式的简单应用
7: class FibonacciAdapter
8: {
9: private:
10: FibonacciGenerator f; // 对象适配器
11: int length;
12: public:
13: FibonacciAdapter(int size) : length(size){ }
14:
15: //inner class, 为 FibonacciAdapter 提供迭代器操作
16: class iterator;
17: friend class iterator;
18: class iterator : public std::iterator<
19: std::input_iterator_tag, FibonacciAdapter, ptrdiff_t>
20: {
21: private:
22: // 迭代器, iterator 仅获得一个包含 FibonacciAdapter 的引用
23: // 这样它就能够访问 FibonacciGenerator 和 length
24: FibonacciAdapter& ap;
25: public:
26: typedef int value_type;
27: iterator(FibonacciAdapter& a) : ap(a){ }
28: bool operator==(const iterator&) const{
29: //相等判断忽略了右边的值,因为惟一重要的问题是判断发生器是否达到其长度
30: return ap.f.count() == ap.length;
31: }
32: bool operator!=(const iterator& x) const{
33: return !(*this == x);
34: }
35: /
36: int operator*() const {
37: return ap.f();
38: }
39: // operator++() 没有修改迭代器
40: // 改变 FibonacciGenerator 状态的惟一操作是调用发生器
41: // FibonacciGenerator 中的函数 operator()
42: iterator& operator++(){
43: return *this;
44: }
45: iterator operator++(int){
46: return *this;
47: }
48: };
49:
50: // 为 FibonacciAdapter 提供迭代器的 begin, end 操作
51: iterator begin(){
52: return iterator(*this);
53: }
54: iterator end(){
55: return iterator(*this);
56: }
57: };
1: //test.cpp
2:
3: #include "FibonacciAdapter.h"
4: #include <iostream>
5: #include <algorithm>
6: #include <iterator>
7:
8: template<typename Iter>
9: void PrintSequence(Iter first, Iter last, const char* nm = "",
10: const char* sep = " ",
11: std::ostream& os = std::cout)
12: {
13: if(nm != 0 && *nm != '/0')
14: os << nm << ": " << sep;
15:
16: typedef typename std::iterator_traits<Iter>::value_type T;
17: std::copy(first, last, std::ostream_iterator<T>(std::cout, sep));
18:
19: os << std::endl;
20: }
21:
22: int main()
23: {
24: const int SZ = 10;
25:
26: FibonacciAdapter a0(SZ);
27: PrintSequence(a0.begin(), a0.end(), "initial: ", " ");
28:
29: FibonacciAdapter a1(SZ);
30: //accumulate: 计算序列的和
31: std::cout << "accumulate: "
32: << accumulate(a1.begin(), a1.end(), 0) << std::endl;
33:
34: FibonacciAdapter a2(SZ), a3(SZ);
35: //inner_product: 计算两个序列的内积
36: std::cout << "inner product: "
37: << inner_product(a2.begin(), a2.end(), a3.begin(), 0) << std::endl;
38:
39: FibonacciAdapter a4(SZ);
40: int r1[SZ] = {0};
41: // partial_sum: 部分和; r1[0] = a1[0]; r1[1] = a1[0]+a1[1]; r1[2] = a1[0]+a1[1]+a1[2] ....
42: int* end = partial_sum(a4.begin(), a4.end(), r1);
43: PrintSequence(r1, end, "partial_sum", " ");
44:
45: FibonacciAdapter a5(SZ);
46: int r2[SZ] = {0};
47: // adjacent_difference: 计算序列中连续两个元素的差
48: end = adjacent_difference(a5.begin(), a5.end(), r2);
49: PrintSequence(r2, end, "adjacent_difference", " ");
50:
51: return EXIT_SUCCESS;
52: }