Do You PHP?    
Search Engine Optimization  php5 powerd  Valid XHTML 1.0!  Valid CSS!  このサイトのはてなブックマーク数 



last updated
2002/07/04

counter hits
since 1999/11/06


PHP4でデザインパターン(Protptype編)

オブジェクト指向についてはまだまだ勉強中ですが、「PHPでGoFのデザインパターンを実装したら、どんな感じになるんだろ?」と思ってしまったので、ちょっとずつやってみることにしました。

caution間違いやご意見がありましたら、遠慮なくツッコミを入れてくださいm(_"_)m

今回は、Protptypeパターンで「インスタンスをコピーして新しいインスタンスを作成する」パターンです(以下のクラス図を参照)。

Protptypeパターンのクラス図

今回のサンプルは、あるオブジェクトのインスタンス変数に値を設定した後、コピーして別のオブジェクトを作成します。また、新しいオブジェクトのインスタンス変数の値を変更し、コピー元となったオブジェクトのそれと比較します。

以下がサンプルコードです。

●Protptype.php

<?php
class ClassA
{
    function create() { return $this; }
}

class ClassB extends ClassA
{
    var $name_;
    function ClassB()
    {
        $this->name_ = "";
        $this->code_ = "";
        $this->amount_ = 0;
    }
    function setName($name) { $this->name_ = $name; }
    function setCode($code) { $this->code_ = $code; }
    function setAmount($amount) { $this->amount_ = $amount; }

    function getResult()
    {
        return $this->name_ . "/"
             . $this->code_ . "/"
             . $this->amount_;
    }
}
?>
<?php
    /**
     * main
     */
    $b1 = new ClassB();
    $b1->setName("広島県人@埼玉在住");
    $b1->setCode("001");
    $b1->setAmount(123);

    /**
     * クローンの作成
     * Zend1.0では、常にオブジェクトのコピーになるため、
     * 通常の代入「=」でもOK
     */
    $b2 = $b1->create();
//    $b2 = $b1;

    /**
     * 片方だけ値を変更
     */
    $b2->setName("Prototypeパターンのテストです");

    /**
     * 結果の表示
     */
    echo phpversion() . "<br/>";
    echo "\$b1=" . $b1->getResult() . "<br/>";
    echo "\$b2=" . $b2->getResult() . "<br/>";

?>

●実行結果
4.2.1
$b1=広島県人@埼玉在住/001/123
$b2=Prototypeパターンのテストです/001/123

コメントにも書いてありますが、PHP4で採用されているZend Engine(以下ZE)1.0では、オブジェクトは値渡しになるため、代入「=」することでオブジェクトがコピーされます。ですので、Javaの「clone」を意識する必要は特にありません。

しかし、ZE2の場合は、オブジェクトは全て参照渡しになるため、代入「=」するだけではオブジェクトはコピーされません。この場合、「__clone()」という特殊なメソッドを使うことになります。以下が、ZE2の場合のサンプルになります。こちらで動作とソースを確認できます。

●Prototype_ze2.php

<?php
class ClassA
{
    function create()
    {
        /**
         * $this->__clone()が使えないようなので、
         * とりあえず小細工。。。
         */
        $obj = $this;
        return $obj->__clone();
    }
}

class ClassB extends ClassA
{
    var $name_;
    function ClassB()
    {
        $this->name_ = "";
        $this->code_ = "";
        $this->amount_ = 0;
    }
    function setName($name) { $this->name_ = $name; }
    function setCode($code) { $this->code_ = $code; }
    function setAmount($amount) { $this->amount_ = $amount; }

    function getResult()
    {
        return $this->name_ . "/"
             . $this->code_ . "/"
             . $this->amount_;
    }

}
?>
<?php
    /**
     * main
     */
    $b1 = new ClassB();
    $b1->setName("広島県人@埼玉在住");
    $b1->setCode("001");
    $b1->setAmount(123);

    /**
     * クローンの作成
     * Zend2.0では、オブジェクトは参照渡しになる。
     * $b2 = $b1->__clone(); でも可
     */
    $b2 = $b1->create();

    /**
     * 片方だけ値を変更
     */
    $b2->setName("Prototypeパターンのテストです");

    /**
     * 結果の表示
     */
    echo phpversion() . "<br/>";
    echo "\$b1=" . $b1->getResult() . "<br/>";
    echo "\$b2=" . $b2->getResult() . "<br/>";
?>



About This Site |  Privacy Policy |  Contact
Copyright © 1999 - 2002 by Hideyuki SHIMOOKA all rights reserved.