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



last updated
2002/06/02

counter hits
since 1999/11/06


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

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

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

今回は、Mementoパターンで、「オブジェクトの状態を保存する」パターン。。。つまり、アンドゥやリドゥを行うためのパターンです(以下のクラス図を参照)。実際に保存されるオブジェクトがMementoクラスで、Originatorクラスが状態の保存・復元を行います。Caretakerクラスは、保存・復元の要求をOriginatorクラスに通知します。ちなみに、Mementoは「記憶」「記念の品」という意味です。

Mementoパターンのクラス図

今回のサンプルは、数値データと文字データを入力していき、任意のタイミングでその時点の状態を保存・復元する、というものです。雰囲気としては、ショッピングカート。。。っぽい。。。かも知れません(^-^;

なお、上のクラス図との関係は、以下のようになります。

  • Caretaker => Main以降のスクリプト
  • Originator => Originator
  • Memento => Data

ということで、以下がサンプルコードです。動作確認は、PHP4.1.2、PHP4.2.0RC2で、register_globalsはOffとしています。

サンプルコードではMementoオブジェクトを1つしか保存できませんが、配列を使うことで、復元を複数回行うこともできます。

●Memento.php

<?php
/**
 * データを入れる器
 */
class Data
{
    var $total_;
    var $comment_;
    function Data()
    {
        $this->total_ = 0;
        $this->comment_ = "";
    }
    function setTotal($val) { $this->total_ = $val; }
    function getTotal() { return $this->total_; }
    function setComment($comment) { $this->comment_ = $comment; }
    function getComment() { return $this->comment_; }
}

/**
 * データ容器の作成とアンドゥを行う
 */
class Originator
{
    var $total_;
    var $comment_;
    function Originator()
    {
        $this->total_ = 0;
        $this->comment_ = "";
    }
    function saveData()
    {
        $data = new Data();
        $data->setTotal($this->total_);
        $data->setComment($this->comment_);
        return $data;
    }
    function restoreData($data)
    {
        $this->total_ = $data->getTotal();
        $this->comment_ = $data->getComment();
    }
    function addTotal($val) { $this->total_ += $val; }
    function getTotal() { return $this->total_; }
    function addComment($comment) { $this->comment_ .= "==>" . $comment . "&lt==\n"; }
    function getComment() { return $this->comment_; }
}
?>
<?php
    /**
     * Main
     */
    session_start();
    if (!isset($_SESSION["originator"])) {
        $originator = new Originator();
        $memento = $originator->saveData();
        $_SESSION["originator"] = $originator;
        echo "新しいSessionを開始します<br>";
    }
    else {
        $originator = $_SESSION["originator"];
        $memento = $_SESSION["memento"];
        echo "Session情報を取り出します<br>";
    }


    if (!isset($_POST["mode"])) { $mode = ""; }
    else { $mode = $_POST["mode"]; }

    if ($mode == "save") {
        $memento = $originator->saveData();
        echo "<font color=\"#880000\">データを保存しました。</font><br>";

    }
    else if ($mode == "restore") {
        $originator->restoreData($memento);
        echo "<font color=\"#008800\">データをアンドゥしました。</font><br>";
    }
    else {
        if (!isset($_POST["val"])) { $val = 0; }
        else { $val = $_POST["val"]; }
        $originator->addTotal($val);

        if (!isset($_POST["comment"])) { $comment = ""; }
        else { $comment = $_POST["comment"]; }
        $originator->addComment($comment);
    }

    $_SESSION["originator"] = $originator;
    $_SESSION["memento"] = $memento;

    echo "現在の合計:" . $originator->getTotal() . "<br>";
    echo "現在のコメント:<br>" . nl2br($originator->getComment()) . "<br>";
?>
<form action"Memento.php" method="post">
追加する値:<input type="text" name="val" value="0"><br>
コメント:<input type="text" name="comment" value=""><br>
<input type="submit" name="mode"> 
<input type="submit" name="mode" value="save"> 
<input type="submit" name="mode" value="restore">
</form>
●出力結果1(初期画面)
新しいSessionを開始します
現在の合計:0
現在のコメント:
==><==  
●出力結果2(数値として1,2,3、コメントに「n回目です」を順に入力した後)
Session情報を取り出します
現在の合計:6
現在のコメント:
==>1回目です<==
==>2回目です<==
==>3回目です<==
  
●出力結果3(saveをクリックし、現在の状態を保存)
Session情報を取り出します
データを保存しました。
現在の合計:6
現在のコメント:
==><==
==>1回目です<==
==>2回目です<==
==>3回目です<==
  
●出力結果4(数値として4、コメントに「4回目です」を順に入力した後)
Session情報を取り出します
現在の合計:10
現在のコメント:
==>1回目です<==
==>2回目です<==
==>3回目です<==
==>4回目です<==
  
●出力結果5(アンドゥ後)
Session情報を取り出します
データをアンドゥしました。
現在の合計:6
現在のコメント:
==><==
==>1回目です<==
==>2回目です<==
==>3回目です<==
  


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