Adapter パターン

Adapter パターン（アダプター・パターン）とは、GoF (Gang of Four; 4人のギャングたち) によって定義されたデザインパターンの1つである。Adapter パターンを用いると、既存のクラスに対して修正を加えることなく、インタフェースを変更することができる。Adapter パターンを実現するための手法として継承を利用した手法と委譲を利用した手法が存在する。それぞれについて以下の節で説明する。

継承を利用したAdapter 
継承を利用したAdapterは、利用したいクラスのサブクラスを作成し、そのサブクラスに対して必要なインタフェースを実装することで実現される。

サンプルプログラム 
下記の例において、Productクラスは既存のクラスであり修正できないものとする。
ここで、Productクラスを利用したい開発者がいて、
その開発者はgetPriceというメソッドでProductの値段を取得したいとする。
この場合、ProductAdapterというAdapterを作成することで、既存クラス(Product)クラスを修正することなく、
異なるインタフェースを持たせることができる。
このように、既存クラスを修正することなく、異なるインタフェースを持たせるということが、Adapter パターンの役割である。
interface ProductPrice{
  public int getPrice();
}

class Product{
  private int cost;
  public int getCost(){
    return cost;
  }
}

class ProductAdapter extends Product implements ProductPrice{
  public int getPrice(){
    return this.getCost();
  }
}

クラス図 
継承を利用したAdapterのクラス図は以下のようになる。

参考までに、上のサンプルコードとこのクラス図との対応を示す。

TargetProductPrice
Target#requiredMethodProductPrice#getPrice()
AdapterProductAdapter
Adapter#requiredMethodProductAdapter#getPrice()
AdapteeProduct
Adaptee#oldMethodProduct#getCost()

委譲を利用したAdapter 
委譲を利用したAdapterは、利用したいクラスのインスタンスを生成し、そのインスタンスを他クラスから利用することで実現される。

サンプルプログラム 
interface ProductPrice{
  public int getPrice();
}

class Product{
  private int cost;
  public int getCost(){
    return cost;
  }
}

class ProductAdapter implements ProductPrice{
  private Product product = new Product();
  public int getPrice(){
    return product.getCost();
  }
}

クラス図 
委譲を利用したAdapterのクラス図は以下のようになる。

※上図において、extendsはimplementsでも良い。

こちらのほうも、参考までにサンプルコードの対応を示す。

TargetProductPrice
Target#requiredMethod()ProductPrice#getPrice()
AdapterProductAdapter
Adapter#requiredMethod()ProductAdapter#getPrice()
AdapteeProduct
Adaptee#oldMethod()Product#getCost()

デザインパターン (ソフトウェア)