『Java言語で学ぶデザインパターン入門』をPHPで実習する 第2章Adapterパターン

増補改訂版Java言語で学ぶデザインパターン入門

本記事に掲載したサンプルコードは、https://github.com/ryo-utsunomiya/design_patternでも公開中です。

Adapterパターンとは

Adapterパターンとは、2つのオブジェクトの間にギャップが有る時に、そのギャップを埋めるオブジェクトを用意することです。

継承によるAdapter

例えば、以下のクラスが既存のクラスとして存在しているとします。

<?php

namespace my;

class Banner
{
    /**
     * @var string
     */
    private $string;

    /**
     * @param $string
     */
    public function __construct($string)
    {
        $this->string = (string)$string;
    }

    public function showWithParen()
    {
        printf("(%s)n", $this->string);
    }

    public function showWithAster()
    {
        printf("*%s*n", $this->string);
    }
}

このクラスは、与えられた文字列を()または**でくくって表示するメソッドを持っています。

ここで、「printWeak()」と「printStrong()」というメソッドを定義したいとします(ここでは、なぜこのメソッドの実装が必要なのかは問題にしません)。

実装方法の一例として、以下のインタフェースを定義します。

<?php

namespace my;

interface IPrint
{
    public function printWeak();

    public function printStrong();
}

これを満たしつつ、既存のクラスを再利用すると、以下のようなAdapterが実装できます。

<?php

namespace my;

class PrintBanner extends Banner implements IPrint
{
    public function printWeak()
    {
        $this->showWithParen();
    }

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

これが、継承を使ったAdapterパターンです。既存のBannerのメソッドを利用しつつ、printWeak()とprintStrong()を実装しています。

委譲によるAdapter

Adapterパターンは委譲を使っても実装できます。委譲を使う場合、インタフェースではなく、抽象クラスを使うことになります。

<?php

namespace my;

abstract class AbstractPrint
{
    abstract protected function printWeak();
    abstract protected function printStrong();
}

これを継承したクラスで、printWeak()とprintStrong()を実装します。

<?php

namespace my;

class PrintBanner extends AbstractPrint
{
    /**
     * @var Banner
     */
    private $banner;

    /**
     * @param string $string
     */
    public function __construct($string)
    {
        $this->banner = new Banner((string)$string);
    }

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

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

継承と委譲のどちらがより優れているということはありません。利用したいオブジェクトや、完成品の形などから、適切な方法を選ぶことになります。

コメントを残す

コメントを残す