LoginSignup
5
8

More than 5 years have passed since last update.

PHPで学ぶデザインパターン(Adapterパターン)

Posted at

Adapterパターンとは

異なる2つのインターフェース(API)の間に入って、その差を埋めるためのデザインパターンのことをAdapterパターンと呼びます。
すでにあるものと必要なものの間に入ってその差を埋めるようなイメージです。

AクラスがBクラスを呼び出そうとする際に、何かしらの不都合があって呼び出せないとしましょう。
その際にBクラスを変更するのではなく、新しくCクラスを作成して、AクラスはCクラス経由でBクラスを呼び出そうとする仕組みです。
図にするとこんな感じですかね。

スクリーンショット 2017-04-18 23.00.29.png

Adapterパターンで登場する概念

  1. Target
    必要となるメソッドを定義しています。
    先ほどの例でいうところの吹き出しに当てはまります。

  2. Client
    呼び出し元
    先ほどの例でいうところのAクラスに当てはまります。

  3. Adaptee
    適合される側のことで、すでに何かしらのメソッドを持っています。
    先ほどの例でいうところのBクラスに当てはまります。

  4. Adapter
    今回のデザインパターンのメイン部分です。
    clientとadapteeの間に入り、targetを満たすようにします。
    先ほどの例でいうところのCクラスに当てはまります。

簡単なコードを書いてみる

Adaptee

既存のコードと仮定します。元々Bannerクラスはあったとしましょう。

class Banner
{
    private $string;

    public function __construct($string)
    {
        $this->string = $string;
    }

    public function showWithParen()
    {
        echo "(" . $this->string . ")";
    }

    public function showWithAster()
    {
        echo "*" . $this->string . "*";
    }
}

Target

clientから先ほどのBannerクラスを直接呼び出せないと仮定し、adapterパターンを使ってそれを解決したいです。
解決するために必要なメソッドを考えinterfaceとして定義しておきます。

interface Output
{
    public function outputWeak();

    public function outputStrong();
}

Adapter

clientとadapteeの間に入り、targetを満たすようにadapterを作成します。
これにより既存のadpteeであるBannerクラスには変更を加えずに、clientから呼び出せるようになりました。

class OutputBanner extends Banner implements Output
{
    public function __construct($string)
    {
        parent::__construct($string);
    }

    public function outputWeak()
    {
        $this->showWithParen();
    }

    public function outputStrong()
    {
        $this->showWithAster();
    }
}

Client

ここでadapterであるOutputBannerクラスを呼び出します。

class Main
{
    public function main()
    {
        $ob = new OutputBanner("hoge");
        $ob->outputWeak();
        $ob->outputStrong();
    }
}

メリット

既存のコードを再利用しやすいということと、既存のコードに手を加えなくて済むということでしょうか。
手を加えなければテストコードを書き換える必要もありませんし、不具合があっても対象が追加したadapterの部分であるということはわかりやすいと思います。

実務で使っている場面

自分が触っているプロダクトでは、一部ソースコードのリプレイスを行いました。
そのため極力リプレイス前の古いコードは直接使用しないように、このadapterパターンを使っています。
古いコードを再利用しつつ、リプレイス後のディレクトリへコードを書き、リプレイス前のコードは直接使用しないようにしています。

参考

Java言語で学ぶデザインパターン入門
Do You PHP
TECHSCORE

5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8