一些面向對象的編程方式,提供了一種構建對象間復雜網絡互連的能力。當對象們連接在一起時,它們就可以相互提供服務和信息。這個模式對於大型系統項目來說應該是挺挺有用的,通俗的講,這種模式允許某個類去觀察另一個類。當一個類被改變時,觀察類就會收到通知並且做出相應的動作。
在平時的項目中還是挺有用的,比如一個用戶下了一筆訂單,下單成功後,就需要去發送短信/郵件的通知,庫存的修改,賬戶余額的修改等等很多操作。
在之後的PHP5.0起,內置的SPL標准庫中就提供了這種設計模式接口供大家使用,接下了就通過實例來學習一下。
SPL 提供了 SplSubject 和 SplObserver 接口。
SplSubject 接口提供了attach()、detach()、notify() 三個方法。而 SplObserver 接口則提供了 update()方法。
<?php /** * 這一模式的概念是SplSubject類維護了一個特定狀態,當這個狀態發生變化時,它就會調用notify()方法。 * 調用notify()方法時,所有之前使用attach()方法注冊的SplObserver實例的update方法都會被調用。 * */ interface SplSubject{ public function attach(SplObserver $observer);//注冊觀察者 public function detach(SplObserver $observer);//釋放觀察者 public function notify();//通知所有注冊的觀察者 } interface SplObserver{ public function update(SplSubject $subject);//觀察者進行更新狀態 } ?>
使用所提供的接口,來實現觀察者模式
<?php /** *具體目標 */ class Salary implements SplSubject { private $observers, $money; public function __construct() { $this->observers = array(); } public function attach(SplObserver $observer) { //注冊觀察者 $this->observers[] = $observer; } public function detach(SplObserver $observer) { //釋放觀察者 if($idx = array_search($observer,$this->observers,true)) { unset($this->observers[$idx]); } } public function notify() { //通知所有觀察者 foreach($this->observers as $observer) { $observer->update($this); } } public function payoff($money) { //發工資方法 $this->money = $money; $this->notify(); //通知觀察者 } } /** * 具體觀察者 */ class Programmer1 implements SplObserver { public function update(SplSubject $subject) { echo 'Programmer1 發工資了!<br/>'; } } class Programmer2 implements SplObserver { public function update(SplSubject $subject) { echo 'Programmer2 也發工資了!<br/>'; } } $subject = new Salary(); $observer1 = new Programmer1(); $observer2 = new Programmer2(); //注冊觀察者 $subject->attach($observer1); $subject->attach($observer2); //發工資操作,發起通知 $subject->payoff('20K'); ?>
通過Observer模式,把一對多對象之間的通知依賴關系的變得更為松散,大大地提高了程序的可維護性和可擴展性,也很好的符合了開放-封閉原則。東西是不錯,如何能夠更好的去使用它,仍需要多加實踐、聯系。