デザインパターン「Adapter」

# はじめに
本投稿は<a href="http://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/ref=sr_1_1?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" target="_blank">Java言語で学ぶデザインパターン入門</a>のデザインパターンをまとめた記事です。今回はSingletonパターンになります。
[まとめ一覧はこちら](#design_pattern)

# Adapterパターン
<p align="center"><img width="550" alt="スクリーンショット 2016-02-07 21.12.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/1c4367ad-cadc-04f8-0107-ebd004345096.png"></p>


## Adapterとは
Adapterとは***適合する***という意味で、***Wrapperパターン***と呼ばれることもあります。
「すでに提供されているもの」を「利用できるもの」にするためのデザインパターンで、本書ではAC電源とノートパソコンの間の***ACアダプター***を例として説明されています。

利用場面として以下が考えられます

- 関連性のないクラス通しを既存のクラスを変えずに関連付けする場合
- 既存のクラスをある新しいインターフェイスを通じて再利用したい場合
- 既存のクラス・インターフェイスをアプリケーション固有なものに(使いやすく)したい場合

## Adapterパターンのクラス図
<p align="center"><img width="1001" alt="スクリーンショット 2016-02-07 21.39.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/2b4c30be-d177-8280-56c6-50dd8aaedfa3.png"></p>


- 利用する側はAdapterを生成し、Target[インタフェースまたは抽象クラス]を利用する
- Adapterは継承または委譲を使ってAdapteeを利用する

## 具体例

今回はプロパティをストリームから読み書きする`java.util.Properties`クラスをAdapterパターンを使ってFilePropertiesクラスを作っていきます

- Target: [FileIoインタフェース](#target)
- Adapter: [FilePropertiesクラス](#adapter)
- Adaptee: `java.util.Properties`クラス

`java.util.Properties`クラスは以下のメソッドが利用できます
<dl>
 <dt>`void load(InputStream in) throws IOException`</dt>
 <dd>プロパティの集合をInputStreamから読み込む</dd><br>
 <dt>`void store(OutputStream out, String header) throws IOException`</dt>
 <dd>プロパティの集合をOutputStreamから書き込む(header: コメント文字列)</dd>
</dl>

### Mainクラス
以下のように`file.txt`にプロパティを書き込んで`newfile.txt`で保存処理をしていきたいと思います

```java:Main.java
public static void main(String[] args) {
		FileIo fileIo = new FileProperties();//※
		try {
			fileIo.readFromFile("file.txt");
			fileIo.setValue("Apple", "iPhone");
			fileIo.setValue("Google", "Android");
			fileIo.setValue("Git", "Hub");
			fileIo.setValue("DesignPattern", "Adapter");
			fileIo.writeToFile("newfile.txt");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
```

※ fileIoインターフェイスのメソッドを用いることを強調するために、`FileIo`型の変数に代入している

### <a id="target">Target</a>

- 基本的な読み書きの処理を宣言

```java:FileIo.java
import java.io.*;

public interface FileIo {
	public void readFromFile(String filename) throws IOException;
	public void writeToFile(String filename) throws IOException;
	public void setValue(String key, String value);
	public String getValue(String key);
}
```

### <a id="adapter">Adapter</a>

- FileIoインタフェースを実装

```java:FileProperties.js
import java.util.*;
import java.io.*;

public class FileProperties extends Properties implements FileIo {
	public void readFromFile(String filename) throws IOException {
		load(new FileInputStream(filename));
	}
	
	public void writeToFile(String filename) throws IOException {
		store(new FileOutputStream(filename), "Written by FileProperties");
	}
	
	public void setValue(String key, String value) {
		setProperty(key, value);
	}
	
	public String getValue(String key) {
		return getProperty(key, "");
	}
}
```

## 実行結果

実行前

```tex:file.tex
Apple=iPod
```

実行後

```tex:newfile.tex
#Written by FileProperties
#Sun Feb 07 20:49:50 JST 2016
DesignPattern=Adapter
Apple=iPhone
Git=Hub
Google=Android
```

実行してみると、テキストが書き換えられているのがわかるかと思います

# 追記

- 既存のクラスを書き換えずにAdapterパターンを利用することのメリット
 - 既存のクラス(Adaptee)をもう一度テストする必要がなくなる
 - Adapterパターンによってバグが発生しても、既存のクラス(Adaptee)にバグがないことが保証される
- Adaptee役とTargetの機能がかけ離れてる場合は、Adapterパターンは非推奨
- Targetをクラスすることで、委譲を利用したAdapterパターンも可能(AdapterでAdapteeのインスタンスを保持)

### サンプルコードについて

以下のレポジトリにソースコードをアップしてあります。

[shoheiyokoyama/design-pattern_java](https://github.com/shoheiyokoyama/design-pattern_java/tree/master/Adapter)

# <a id="design_pattern">デザインパターン</a>
- 生成に関するパターン
 - Abstract factory
 - Builder
 - <a href="http://qiita.com/shoheiyokoyama/items/d752834a6a2e208b90ca" target="_blank">Factory Method</a>
 - <a href="http://qiita.com/shoheiyokoyama/items/61826e158b3c4a259065" target="_blank">Prototype</a>
 - <a href="http://qiita.com/shoheiyokoyama/items/c16fd547a77773c0ccc1" target="_blank">Singleton</a>
- 構造に関するパターン
 - <a href="http://qiita.com/shoheiyokoyama/items/bd1c692db480b640c976" target="_blank">Adapter</a>
 - Bridge
 - Composite
 - Decorator
 - Facade
 - Flyweight
 - Proxy
- 振る舞いに関するパターン 
 - Chain of responsibility
 - Command
 - Interpreter
 - <a href="http://qiita.com/shoheiyokoyama/items/3f42d0057d9d5a861039" target="_blank">Iterator</a>
 - Mediator
 - Memento
 - <a href="http://qiita.com/shoheiyokoyama/items/d4b844ed29f84a80795b" target="_blank">Observer</a>
 - State
 - Strategy
 - <a href="http://qiita.com/shoheiyokoyama/items/c2ce16b4f492cd014d50" target="_blank">Template Method</a>
 - Visitor

# 参考文献
<a href="http://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/ref=sr_1_1?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" target="_blank">Java言語で学ぶデザインパターン入門</a>