|
zip形式
tgz形式
オブジェクト指向についてはまだまだ勉強中ですが、「PHPでGoFのデザインパターンを実装したら、どんな感じになるんだろ?」と思ってしまったので、ちょっとずつやってみることにしました。
間違いやご意見がありましたら、遠慮なくツッコミを入れてくださいm(_"_)m
今回は、Observerパターンで、「学級委員がいたずらっ子を先生にチクる」。。。違う、「観察者が観察対象の状態変化に応じた処理を行う」パターンです(以下のクラス図を参照)。
今回のサンプルは、時間がかかる検索時のプログレスバーもどきです(ちょっと強引ですが。。。)。実際には検索を行わないで、sleep関数で1秒ずつ一時停止させることで、擬似的に「重い処理」を実現しています。また、プログレスバーとして「+」マークを表示するものと、現在の呼出し回数を表示するものを用意しました。
簡単なクラスの説明ですが、「観察者」はWaitObserverクラスとCountObserverクラス、「観察対象」はWaitクラスのサブクラスであるSearchクラスになります。Searchクラスで処理が実行され、WaitObserverクラスに「+」マークを表示するようObserverに通知します(WaitクラスのスーパークラスであるAbstractSubjectに定義されたnotifyObserversメソッド)。また、CountObserverに現在何回目の呼出しかを表示させるよう、同メソッドで通知します(以下のクラス図を参照)。
ということで、以下がサンプルコードです。また、Abstractクラスなどを含めたスクリプトコードは、上のリンクからダウンロードできます。解凍後に作成されるObserverTest.htmlにアクセスしてください。動作確認は、PHP4.1.2、PHP4.2.0RC2で、register_globalsはOffとしています。
また、コード内部のiteratorクラスは、黒木さんがphp-usersで投稿されたIteratorクラスを使わせていただいていますm(_"_)m
●ObserverTest.php
<?php
require_once("Search.phl");
require_once("WaitObserver.phl");
require_once("CountObserver.phl");
?>
<?php
session_start();
$s = new Search();
$s->addObserver(new WaitObserver());
$s->addObserver(new CountObserver());
$s->setNextURL("Result.php");
$s->execute();
?>
●AbstractSubject.phpの抜粋
<?php
class AbstractSubject
{
:
function notifyObservers()
{
$it = new Iterator($this->observer_);
while ($it->hasNext()) {
$observer = $it->next();
$observer->update($this);
}
$this->count_++;
}
:
}
?>
●Wait.phpの抜粋
<?php
class Wait extends AbstractSubject
{
:
function execute()
{
:
for ($i = 0; $i < 5; $i++) {
sleep(1);
$this->notifyObservers();
}
:
}
?>
●ObserverTest.php
<?php
class WaitObserver extends Observer
{
function update($obj)
{
echo "+";
flush();
}
}
?>
●出力結果(処理後の画面)
Array ( [Author] => shimooka@doyouphp.jp [Pattern] => Observer )
|