観察対象の状態が変化すると、通知する
Subject(被験者):NumberGenerator
Observerを登録・削除するメソッド、現在の状態を取得するメソッドをもつ
具体的なSubject:RandomNumberGenerator
状態が変化したらObserverに伝える
Observer(観察者):Observer
具体的なObserver:DigitObserver、GraphObserver
updateが呼ばれると、Subjectの現在の状態を取得して何か処理をする
Observer.php
interface Observer { function update(NumberGenerator $generator): void; }
NumberGenerator.php
abstract class NumberGenerator { private $observers = []; function addObserver(Observer $observer): void { $this->observers[] = $observer; } function deleteObserver(Observer $observer): void { foreach ($this->observers as $key => $val) { if ($val == $observer) unset($this->observers[$key]); } } function notifyObservers(): void { foreach ($this->observers as $observer) { $observer->update($this); } } abstract function getNumber(): int; abstract function execute(): void; }
RandomNumberGenerator.php
class RandomNumberGenerator extends NumberGenerator { private $number; function getNumber(): int { return $this->number; } function execute(): void { for ($i=0;$i<3;$i++) { $this->number = rand(1, 20); $this->notifyObservers(); } } }
DigitObserver.php
class DigitObserver implements Observer { function update(NumberGenerator $generator): void { echo "DigitObserver:" . $generator->getNumber() . "\n"; sleep(1); } }
GraphObserver.php
class GraphObserver implements Observer { function update(NumberGenerator $generator): void { $str = ""; $count = $generator->getNumber(); for ($i=0;$i<$count;$i++) { $str .= "*"; } echo "GraphObserver:" . $str . "\n"; sleep(1); } }
Main.php
require "../autoload.php"; $generator = new RandomNumberGenerator(); $dObserver = new DigitObserver(); $gObserver = new GraphObserver(); $generator->addObserver($dObserver); $generator->addObserver($gObserver); $generator->execute();
autoload.php
function autoload($className){ require './'.$className.'.php'; } spl_autoload_register('autoload');