适配器模式:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原来由于接口不兼容而不能一起工作的那些类可以一起工作。
角色:
(1)Target:这是客户所期待的接口,Target可以是具体的或抽象的类,也可以是接口。
(2)Adaptee:需要适配的类。
(3)Adapter:通过在内部包装一个Adaptee对象,把源接口转换成目标接口。
Client需要Request()函数,Adaptee提供的是SpecificRequest()函数,Adapter提供一个Request()函数将Adaptee和SpecificeRequest()函数封装起来。
什么时候用?
(1)在想使用一个已存在的类,但是如果他的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。
(2)用了适配器模式,客户代码可以统一调用统一接口就行了,这样可以更简单,更直接,更紧凑。
(3)要在双方都不太容易修改的时候再使用适配器模式适配,而不是一有不同是就使用它。
1 #include <iostream> 2 #include <cstdlib> 3 #include<string> 4 5 6 using namespace std; 7 8 9 //Target,此处为运动员 10 class Player 11 { 12 protected: 13 std::string name; 14 public: 15 Player(std::string name) 16 { 17 this->name = name; 18 } 19 virtual void Attack() = 0; 20 virtual void Defense() = 0; 21 }; 22 23 24 //下面是普通的 接口和Target接口一样的 3个子类, 25 //前锋 26 class Forwards :public Player 27 { 28 public: 29 Forwards(std::string name) :Player(name){} 30 31 void Attack() 32 { 33 std::cout << "前锋 " << name << " 进攻" << std::endl; 34 } 35 36 void Defense() 37 { 38 std::cout << "前锋 " << name << " 防守" << std::endl; 39 } 40 }; 41 42 //中锋 43 class Center :public Player 44 { 45 public: 46 Center(std::string name) :Player(name){} 47 48 void Attack() 49 { 50 std::cout << "中锋 " << name << " 进攻" << std::endl; 51 } 52 53 void Defense() 54 { 55 std::cout << "中锋 " << name << " 防守" << std::endl; 56 } 57 }; 58 59 //后卫 60 class Guards :public Player 61 { 62 public: 63 Guards(std::string name) :Player(name){} 64 65 void Attack() 66 { 67 std::cout << "后卫 " << name << " 进攻" << std::endl; 68 } 69 70 void Defense() 71 { 72 std::cout << "后卫 " << name << " 防守" << std::endl; 73 } 74 }; 75 76 77 78 79 //Adaptee,此处为外籍中锋,它的接口和Target的接口不一样,需要翻译来帮忙转换 80 class ForeignPlayerCenter 81 { 82 private: 83 std::string name; 84 public: 85 void setName(std::string name) 86 { 87 this->name = name; 88 } 89 std::string getName(){ 90 return name; 91 } 92 void ForeignAttack() 93 { 94 std::cout << "外籍中锋 " << name << " 进攻" << std::endl; 95 } 96 97 void ForeignDefense() 98 { 99 std::cout << "外籍中锋 " << name << " 防守" << std::endl; 100 } 101 102 }; 103 104 //Adapter,此处为翻译 ,将 ForeignPlayerCenter 与player 一致的接口 105 class Translator :public Player 106 { 107 private: 108 ForeignPlayerCenter* wjzf; 109 public: 110 Translator(std::string name) :Player(name) 111 { 112 wjzf = new ForeignPlayerCenter; 113 wjzf->setName(name); 114 } 115 ~Translator() 116 { 117 delete wjzf; 118 } 119 void Attack() 120 { 121 wjzf->ForeignAttack(); 122 } 123 124 void Defense() 125 { 126 wjzf->ForeignDefense(); 127 } 128 }; 129 130 131 //Client 132 void main() 133 { 134 Player* b = new Forwards("巴蒂尔"); 135 b->Attack(); 136 137 Player* m = new Guards("麦克格雷迪"); 138 m->Attack(); 139 140 //翻译告诉姚明,教练让你既要进攻,又要防守 141 Player* ym = new Translator("姚明"); 142 ym->Attack(); 143 ym->Defense(); 144 145 delete b; 146 delete m; 147 delete ym; 148 149 system("pause"); 150 }
https://blog.csdn.net/xiqingnian/article/details/42061705
https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/adapter.html