|
オブジェクト指向についてはまだまだ勉強中ですが、「PHPでGoFのデザインパターンを実装したら、どんな感じになるんだろ?」と思ってしまったので、ちょっとずつやってみることにしました。
間違いやご意見がありましたら、遠慮なくツッコミを入れてくださいm(_"_)m
今回は、Mementoパターンで、「オブジェクトの状態を保存する」パターン。。。つまり、アンドゥやリドゥを行うためのパターンです(以下のクラス図を参照)。実際に保存されるオブジェクトがMementoクラスで、Originatorクラスが状態の保存・復元を行います。Caretakerクラスは、保存・復元の要求をOriginatorクラスに通知します。ちなみに、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 . "<==\n"; }
function getComment() { return $this->comment_; }
}
?>
<?php
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回目です<==
|