デザインパターン（Design Pattern）#Adapter

設計を意識したコードが書けるようになる為に、デザインパターン修行しました。
他のDesign Patternもちょくちょく出していきます。

## 前置き
* [増補改訂版Java言語で学ぶデザインパターン入門](http://www.hyuki.com/dp/)をJavaからPythonにしてます。（Pythonは3.4.2）
* [githubにコード置いてあります（まだ動かないものもある）](https://github.com/Nirperm/Design-Pattern)

デザインパターンをどういう時に、何を、どう使うのかを理解することが一先ずの目標。
（Javaというか静的型付言語は初めてで、且つpython歴もそんなに長くないので、Pythonistaぽっくないところがあると思います。ご指摘ございましたらご教授ください。）

今回は、構造に関するパターンAdapter。

## Adapterとは

Adapterパターンには以下の2種がある。
1. クラスによるAdapterパターン（継承を使ったもの）
2. インスタンスによるAdapterパターン（委譲を使ったもの）

２つのクラス間に変換構造を作り、別の用途に使えるように変換する。Apdaterは中間層の役割で、使う方と、使われる方は中身を知らなくても良い。要はクラスで返すのか、インスタンスで返すのかの違いかな。

## 概要
クラスによる継承Apapterパターンを使ったサンプルと委譲によるサンプルプログラムがあります。両者とも与えられた文字列を(文字列)や\*文字列\*のように表示します。

Bannerクラスには、文字列をカッコでくくって表示するshow_with_parenというメソッドと、文字列の前後に\*印を付けて表示するshow_with_parenというメソッドが用意されています。Bannerクラスが既存のものだと仮定します。

Printインタフェースでは、文字列を弱く（カッコ付きで）表示するためのメソッドprint_weakと、文字列を強く表示するためのメソッドprint_strongが宣言されています。

アダプターの役割を担うのがPrinterBannerクラスです。このクラスは、提供されているBannerクラスを継承し、必要とされているPrinterインタフェースを実装する。これでPrinterBannerクラスはアダプターとしての機能を果たすことになります。


## 継承パターンのクラス図
![Adapter継承](https://cacoo.com/diagrams/xuwk5WNopErviEP1-B1284.png?t=1433389487374)

### Adapter 継承パターン

```banner.py
class Banner():

    def __init__(self, string):
        self.__string = string
        
    def show_with_paren(self):
        print('({0})').format(self.__string))
        
    def show_with_aster(self):
        print('({0})').format(self.__string))
```

```printer.py
from abc import ABCMeta, abstractmethod

class Printer(metaclass=ABCMeta):
  
  @abstractmethod
  def print_weak(self):
      pass

  @abstractmethod      
  def print_strong(self):
      pass    
```

```printer_banner.py
from banner import Banner


class PrinterBanner(Banner)

    def __init__(self, string):
        super().__init__(string)

    def print_weak(self):
        self.show_with_paren()
        
    def print_strong(self):
        self.show_with_aster()
```
PrintBannerクラスがAdapterの役割をしています。

Bannerクラスを継承して、show_with_parenメソッドとshow_with_asterメソッドを継承します。

更に、要求されているPrinterインタフェースをしてprint_weakメソッドとprint_strongメソッドを実装してます。
<br>


```main.py
from printer_banner import PrinterBanner

if __name__ == '__main__':
    pb = PrinterBanner('Bye')
    pb.print_weak() 
    pb.print_strong()
```
Printerインタフェースを使ってprint_weak()とprint_strong()で出力している。mainの方では、PrinterBannerクラスがどのような実装になってるか知らないので、mainクラスを変更せずともPrinterBannerクラスの実装を変えることができる。

### Adapter 委譲パターン
委譲によるサンプルプログラムはMainとBannerは継承パターンと同じです。異なるのはPrintBannerクラスだけ。つまり、Bannerクラスを利用して、Printerクラスと同じメソッドを持つクラスを実現しようという。

PrinterBannerクラスは、bannerフィールドでBannerクラスのインスタンスを保持します。このインスタンスはPrinterBannerクラスのコンストラクタで生成します。そして、print_weak及び、print_strongメソッドでは、そのbannerフィールドを介してshow_with_paren, show_with_asterメソッドを呼び出します。

継承を使った方だと、自分のスーパークラスから継承したshow_with_paren, show_with_asterメソッドを呼び出しますが、委譲のパターンではフィールド経由で呼び出しています。

PrinterBannerクラスのprint_weakメソッドが呼ばれた時、自分で処理するのではなく、別のインスタンス（Bannerのインスタンス）のshow_with_parenメソッドにお任せしている。これが委譲になります。

## 委譲パターンのクラス図
![Adapter 委譲](https://cacoo.com/diagrams/vow0jBm8II1sLBqR-B1284.png?t=1433389371863)

```printer_banner.py
from printer import Printer
from banner import Banner


class PrinterBanner(Printer):

     def __init__(self, string):
         self.__banner = Banner(string)

     def print_weak(self):
         self.banner.show_with_paren()

     def print_strong(self):
         self.banner.show_with_aster()

```
今度はPrinterクラスを継承して、まずBannerクラスのインスタンスを呼んでいる。

それで呼んだインスタンスに対してshow_with_parenメソッドとshow_with_asterメソッドを使ってprint_weakメソッドとprint_strongメソッドを実装している。

文言だけ変えてるけど、出力結果は一緒。

```inheritance/main.py
(Bye)
*Bye*
```

```delegation/main.py
(Hello)
*Hello*
```

### まとめ
Adapterパターンは、既存のクラスに一皮かぶせて必要とするクラスを作る。つまり、インタフェースとなる部分が間に入って、異なる二者間のズレを埋め合わせる。

バグが出たとしても、既存のクラスにはバグがないことがわかっているのでAdapter役のクラスを重点的に調べればよいことになり、プログラムのチェックがとても楽になるのと、既存のクラスの仕様だけがわかれば、新しいクラスを作ることができる。

## 参考
* [Wikipedia Software design pattern]([http://en.wikipedia.org/wiki/Software_design_pattern)
[TECHSCORE Adapter パターン 1](http://www.techscore.com/tech/DesignPattern/Adapter/Adapter1.html/)
* [Wikipedia デザインパターン](http://goo.gl/lRi5)
* [Ruby 2.0.0で学ぶ、14個のデザインパターンを作りました[GoF][Design Pattern]](http://morizyun.github.io/blog/ruby-design-pattern-matome-mokuzi/)
* [Rubyによるデザインパターン5原則](http://qiita.com/kidach1/items/4b63de9ad5a97726c50c)