Adapterパターン

# Adapterパターンについて

## 1. はじめに
Adapterパターンは、既に提供されているものがそのまま使えないときに、必要な形に変換して利用するために使用するデザインパターンである。
Adaptorには2種類ある。
- クラスによるAdapter（継承を使ったもの）
- インスタンスによるAdapter（委譲を使ったもの）


この文書では、Adapterパターンの定義、実装方法について記載する。

## 2. Adapterパターンの定義
Adapterパターンは、あるクラスのインタフェースを別のクラスが期待するインタフェースに変換するための構造的パターンである。
これにより、元のクラスを部品として再利用できるようになり、実装/保守コストが大幅に削減される。

## 3. 主要なコンポーネント
Adapterパターンは、以下の主要なコンポーネントから構成されている。

- **Target（対象）**
  - クライアントが期待するメソッドを定める

- **Client（依頼者）**
  - Targetのメソッドを使って処理を行う

- **Adaptee（アダプティー）**
  - 既に用意されているメソッドを持っている

- **Adapter（アダプター）**
  - AdapteeのメソッドをTargetで使えるようにする

## 4. 実装例
### クラス図の紹介
以下のクラス図は、Adapterパターンの構成要素を示している。
※クラス図の都合上、Clientは省く。

#### 継承の場合
```plantuml
@startuml
interface Target {
    targetMethod1()
    targetMethod2()
}

class Adapter {
    targetMethod1()
    targetMethod2()
}

class Adaptee {
    methodA()
    methodB()
    methodC()
}


Target <|-- Adapter : implements <
Adapter --|> Adaptee : extends >
@enduml
```

#### 委譲の場合
```plantuml
@startuml
class Target {
    targetMethod1()
    targetMethod2()
}

class Adapter {
    targetMethod1()
    targetMethod2()
}

class Adaptee {
    methodA()
    methodB()
    methodC()
}


Target <|-- Adapter : extends <
Adapter o--|> Adaptee : has >
@enduml
```



### 具体的なコード例
以下は、JavaでのAdapterパターンの実装例である。
与えられた文字列の表示の強弱を管理する仕様を例にして取り組む。

#### 継承の場合
```java
// Banner.java
public class Banner {
  private String string;
  public Banner(String string) {
    this.string = string;
  }
  public void showWithParen() {
    System.out.println("(" + string + ")");
  }
  public void showWithAster() {
    System.out.println("*" + string + "*");
  }
}


// Print.java
public interface class Print {
  public abstract void printWeak();
  public abstract void printStrong();
}


// PrintBanner.java
public class PrintBanner extends Banner implements Print {
  public PrintBanner(String string) {
    super(string);
  }
  public void printWeak() {
    showWithParen();
  }
  public void printStrong() {
    showWithAster();
  }
}


// AdapterTest.java
public class AdapterTest {
  public static void main(String[] args) {
    Print p = new PrintBanner("Hello");
    p.printWeak();
    p.printStrong();
  }
}
```

#### 委譲の場合
```java
// Banner.java
public class Banner {
  private String string;
  public Banner(String string) {
    this.string = string;
  }
  public void showWithParen() {
    System.out.println("(" + string + ")");
  }
  public void showWithAster() {
    System.out.println("*" + string + "*");
  }
}


// Print.java
public abstract class Print {
  public abstract void printWeak();
  public abstract void printStrong();
}


// PrintBanner.java
public class PrintBanner extends Print {
  private Banner banner;
  public PrintBanner(String string) {
    this.banner = new Banner(string);
  }
  public void printWeak() {
    banner.showWithParen();
  }
  public void printStrong() {
    banner.showWithAster();
  }
}


// AdapterTest.java
public class AdapterTest {
  public static void main(String[] args) {
    Print p = new PrintBanner("Hello");
    p.printWeak();
    p.printStrong();
  }
}
```

## 参考文献
[増補改訂版Java言語で学ぶデザインパターン入門](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030?ie=UTF8&qid=1454743284&sr=8-1&keywords=java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80)