2007年6月27日 星期三

Observer Pattern in PHP5

PHP5.1 後, 新增了 Observer Pattern 的支援.
這個能改變物件依存關係,讓物件狀態一有變動,就自動通知其他相依物件做該做的更新動作, 由程式需要主動呼叫, 改為物件觀察的角色. 這依然是 java 中最常見的特性 awt 以及 MVC 的基楚.
但依然很少人利用.
##CONTINUE##

這篇著重在 PHP5 的 Observer 這個觀念上.
並應用了 SplObjectStorage 這個方便的 Class , 它可以讓您將任何 object 放入其中, 並 iterator 它.

這個不倫不類的例中, 用來承現 PHP 常處理的資料物件上, (因為 PHP 目前尚未有 App Container , 所以暫時 (不會?)用來處理 event 或 listener 上).
我們假設 Teacher / Student / School 都是 DB 上的物件的 ORM , 在以往, 我們需要在 Controller 中處理它的相關性,
並各自呼叫變動的狀態.. 利用 Observer Pattern, 我們能寫出更抽象的 OR 物件, 它僅關心在本身發生了什麼事,
而不需由呼叫端依 Student 或 Teacher 各別處理狀態改變.


<?php

class Teacher implements SplObserver {
private $name;

public function __construct($name) {
$this->name=$name;
}

public function update(SplSubject $subject) {
echo $this->name . " Teacher Says: Hello~~~ \n";
}

}

class Student implements SplObserver {
private $name;

public function __construct($name) {
$this->name=$name;
}

public function update(SplSubject $subject) {
echo $this->name . " Student Says: Hello~~~ \n";
}
}

class School implements SplSubject {

private $name;
private $people ;
private $state;

public function __construct($name) {
$this->people = new SplObjectStorage();
$this->name = $name;
}

public function getName(){
return $this->name;
}
public function attach(SplObserver $observer) {
$this->people->attach($observer);
}

public function detach (SplObserver $observer) {
$this->people->detach($observer);
}

public function notify() {
foreach($this->people as $person) {
$person->update($this);
}
}

public function getState() {
return $this->state;
}

public function setState($state) {
$this->state = $state;
}

}

$school = new School('Rack Lin junior school');

$rack = new Student('rack');
$rack2 = new Student('rack2');
$lily = new Teacher('Lily');
$school->attach($rack);
$school->attach($rack2);
$school->attach($lily);
$school->notify();
?>

Output:

rack Says: Hello~~~
rack Says: Hello~~~
rack2 Says: Hello~~~
rack Says: Hello~~~
rack2 Says: Hello~~~
Lily Says: Hello~~~




Technorati Tags: , ,
張貼留言