Adapter 適配器模式

      Adapter 適配器模式:將一個類的接口轉換成客戶希望的另一個接口。Adapter 模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。Adapter 模式也稱爲包裝器 Wrapper。

     Adapter 模式適用於:1)你想使用一個已經存在的類,而它的接口不符合你的需求。2)你想創建一個可以複用的類,該類可以與其它不相關的類或不可預見的類(跟那些接口可能不一定兼容的類)協同工作。3)(僅適用一對象 Adapter)你想使用一些已經存在的子類,但是不可能對每一個都進行子類化以匹配它們的接口。對象適配器可以適配它的父類接口。

Adapter 的通用結構如下:1)類適配器;2)對象適配器;

1):類適配器,使用多重繼承對一個接口與另一個接口進行匹配。

Adapter

注:使用 C++ 實現適配器類時,Adapter 類應該採用公共方式繼承類 Target 類,並且用私有方式繼承 Adaptee 類。因此,Adater 類應該是 Target 的子類型,但不是 Adaptee 的子類型。

2):對象適配器,使用對象組合:

Adaptee

對象適配器採用採用對象組合的方法將具有不同的類組合在一起。該方法中,適配器 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:  };
   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:  };
//test
   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:  }
 
發佈了54 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章