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

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

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

Prototypeとは

クラスからインスタンスを生成するのではなく、インスタンスから別のインスタンスを作り出すことを、Prototypeパターンと呼びます。

Prototypeパターンの例として、Productという文字列を表示するインタフェースと、Productインスタンスの生成及び管理を行うManagerというクラスが存在するとします。

<?php

namespace myframework;

interface Product {

    /**
     * @param string $s
     */
    public function display($s);
}
<?php

namespace myframework;

class Manager
{
    /**
     * @var Product[]
     */
    private $showCase;

    /**
     * @param string  $name
     * @param Product $proto
     */
    public function register($name, Product $proto)
    {
        $this->showCase[$name] = $proto;
    }

    /**
     * @param string $protoName
     * @return Product
     */
    public function create($protoName)
    {
        if (isset($this->showCase[$protoName])) {
            return clone $this->showCase[$protoName];
        } else {
            throw new InvalidArgumentException();
        }
    }
}

次に、Productインタフェースを実装したUnderlinePenクラスを作成します。このクラスは、与えられた文字列を使用して下線を引きます。

<?php

namespace my;

use myframeworkProduct;

class UnderlinePen implements Product
{
    /**
     * @var string
     */
    private $ulChar;

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

    /**
     * @param string $s
     */
    public function display($s)
    {
        $length  = strlen($s);
        echo '"' . $s . '"' . PHP_EOL;
        echo ' ';
        for ($i = 0; $i < $length; $i++) {
            echo $this->ulChar;
        }
        echo PHP_EOL;
    }
}

以下が、これらのクラスの使用例です。

< ?php

namespace my;

use myframeworkManager;

require_once __DIR__ . '/../autoload.php';

$manager = new Manager();
$manager->register('strong message', new UnderlinePen('~'));
$manager->create('strong message')->display('Hello, World');

これを実行すると、以下のように表示されます。

"Hello, World"
 ~~~~~~~~~~~~

このコードだとありがたみが分かりづらいですが、UnderlinePenのインスタンスを生成するのが難しい場合などには、一度インスタンスを生成しておいて、後で再利用できるようになっていると便利そうですね。

コメントを残す

コメントを残す