Adapter

  • インターフェイスの変換を行い、互換性のないクラスを利用できるようにする
  • 継承アダプタは、クライアントが使用するインターフェイスを実装し、既存のクラスを継承する
  • 委譲アダプタは、クライアントが使用する抽象クラスを実装し、既存クラスの処理を委譲する

  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class Target {
  5. public:
  6. virtual void targetMethod() {
  7. cout << "Original Method." << endl;
  8. }
  9. };
  10.  
  11. class Adaptee {
  12. public:
  13. void Method() {
  14. cout << "Adaptee Method." << endl;
  15. }
  16. };
  17.  
  18. // 継承 Adapter
  19. class DeriveAdapter : public Target, public Adaptee {
  20. public:
  21. virtual void targetMethod() {
  22. Method(); // Adaptee::method()
  23. }
  24. };
  25.  
  26. // 包含 Adapter
  27. class InclusionAdapter : public Target {
  28. public:
  29. virtual void targetMethod() {
  30. _adaptee.Method();
  31. }
  32. private:
  33. Adaptee _adaptee;
  34. };
  35.  
  36. // client
  37. int main() {
  38. Target *t = new Target();
  39. t->targetMethod();
  40. // 継承 Adapter
  41. Target *t1 = new DeriveAdapter();
  42. t1->targetMethod();
  43. // 包含 Adapter
  44. Target *t2 = new InclusionAdapter();
  45. t2->targetMethod();
  46.  
  47. delete t;
  48. delete t1;
  49. delete t2;
  50. return 0;
  51. }
  52.  

出力
Original Method.
Adaptee Method.
Adaptee Method.


http://www.dofactory.com/Patterns/PatternAdapter.aspx#_self1
をC++にした(structural example)
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. // The 'Target' class
  5. class Target {
  6. public:
  7. virtual ~Target() { }
  8. virtual void Request() {
  9. cout << "Called Target Request()" << endl;
  10. }
  11. };
  12.  
  13. // The 'Adaptee' class
  14. class Adaptee {
  15. public:
  16. void SpecificRequest() {
  17. cout << "Called SpecificRequest()" << endl;
  18. }
  19. };
  20.  
  21. // The 'Adapter' class
  22. class Adapter : public Target {
  23. public:
  24. Adapter() {
  25. _adaptee = new Adaptee();
  26. }
  27. virtual ~Adapter() {
  28. delete _adaptee;
  29. }
  30. virtual void Request() {
  31. _adaptee->SpecificRequest();
  32. }
  33. private:
  34. Adaptee *_adaptee;
  35. };
  36.  
  37. // client
  38. int main() {
  39. Target *target = new Adapter();
  40. target->Request();
  41. delete target;
  42. return 0;
  43. }
  44.  

出力
Called SpecificRequest()


http://www.dofactory.com/Patterns/PatternAdapter.aspx#_self2
をC++にした(real world example)
  1. #include <iostream>
  2. #include <string>
  3. #include <ctype.h>
  4. using namespace std;
  5.  
  6. // The 'Target' class
  7. class Compound {
  8. public:
  9. // constructor
  10. Compound(const string &chemical) {
  11. _chemical = chemical;
  12. }
  13. virtual void Display() {
  14. cout << endl << "Compound: " << _chemical << " ------ " << endl;
  15. }
  16. protected:
  17. string _chemical;
  18. float _boilingPoint;
  19. float _meltingPoint;
  20. double _molecularWeight;
  21. string _molecularFormula;
  22. };
  23.  
  24. // The 'Adaptee' class
  25. class ChemicalDatabank {
  26. public:
  27. // 'legacy API'
  28. float GetCriticalPoint(string compound, const string point) {
  29. ToLower(compound);
  30. // Melting Point
  31. if (point == "M") {
  32. if (compound == "water") {
  33. return 0.0f;
  34. }
  35. else if (compound == "benzene") {
  36. return 5.5f;
  37. }
  38. else if (compound == "ethanol") {
  39. return -114.1f;
  40. }
  41. else {
  42. return 0.0f;
  43. }
  44. }
  45. // Biling Point
  46. else {
  47. if (compound == "water") {
  48. return 100.0f;
  49. }
  50. else if (compound == "benzene") {
  51. return 80.1f;
  52. }
  53. else if (compound == "ethanol") {
  54. return 78.3f;
  55. }
  56. else {
  57. return 0.0f;
  58. }
  59. }
  60. }
  61. string GetMolecularStructure(string compound) {
  62. string ret;
  63. ToLower(compound);
  64. if (compound == "water") {
  65. ret = "H2O";
  66. }
  67. else if (compound == "benzene") {
  68. ret = "C6H6";
  69. }
  70. else if (compound == "ethanol") {
  71. ret = "C2H5OH";
  72. }
  73. return ret;
  74. }
  75. double GetMolecularWeight(string compound) {
  76. ToLower(compound);
  77. if (compound == "water") {
  78. return 18.015;
  79. }
  80. else if (compound == "benzene") {
  81. return 78.1134;
  82. }
  83. else if (compound == "ethanol") {
  84. return 46.0688;
  85. }
  86. else {
  87. return 0.0;
  88. }
  89. }
  90. private:
  91. void ToLower(string &str) {
  92. string::iterator it;
  93. for (it=str.begin(); it!=str.end(); ++it) {
  94. *it = tolower(*it);
  95. }
  96. }
  97. };
  98.  
  99. // The 'Adapter' class
  100. class RichCompound : public Compound {
  101. public:
  102. // constructor
  103. RichCompound(const string &name) : Compound(name) {
  104. _bank = NULL;
  105. }
  106. virtual ~RichCompound() {
  107. if (_bank != NULL) delete _bank;
  108. }
  109. virtual void Display() {
  110. if (_bank == NULL) _bank = new ChemicalDatabank();
  111.  
  112. _boilingPoint = _bank->GetCriticalPoint(_chemical, "B");
  113. _meltingPoint = _bank->GetCriticalPoint(_chemical, "M");
  114. _molecularWeight = _bank->GetMolecularWeight(_chemical);
  115. _molecularFormula = _bank->GetMolecularStructure(_chemical);
  116.  
  117. Compound::Display();
  118. cout << " Formula: " << _molecularFormula << endl;
  119. cout << " Weight : " << _molecularWeight << endl;
  120. cout << " Melting Pt: " << _meltingPoint << endl;
  121. cout << " Boiling Pt: " << _boilingPoint << endl;
  122. }
  123. private:
  124. ChemicalDatabank *_bank;
  125. };
  126.  
  127. // client
  128. int main() {
  129. // Non-adapted chemical compound
  130. Compound *unknown = new Compound("Unknown");
  131. unknown->Display();
  132. // Adapted chemical compounds
  133. Compound *water = new RichCompound("Water");
  134. water->Display();
  135. Compound *benzene = new RichCompound("Benzene");
  136. benzene->Display();
  137. Compound *ethanol = new RichCompound("Ethanol");
  138. ethanol->Display();
  139.  
  140. delete unknown;
  141. delete water;
  142. delete benzene;
  143. delete ethanol;
  144. return 0;
  145. }
  146.  

出力
Compound: Unknown ------

Compound: Water ------
Formula: H2O
Weight : 18.015
Melting Pt: 0
Boiling Pt: 100

Compound: Benzene ------
Formula: C6H6
Weight : 78.1134
Melting Pt: 5.5
Boiling Pt: 80.1

Compound: Ethanol ------
Formula: C2H5OH
Weight : 46.0688
Melting Pt: -114.1
Boiling Pt: 78.3


参考サイト

デザインパターンを“喩え話”で分かり易く理解する
http://www.netlaputa.ne.jp/~hijk/study/oo/designpattern.html



デザインパターンの骸骨たち
http://www002.upp.so-net.ne.jp/ys_oota/mdp/

デザインパターンの使い方:Adapter
http://japan.internet.com/developer/20080902/26.html
最終更新:2012年03月02日 06:05