觀察者模式簡介
觀察者模式(Observer)完美的將觀察者和被觀察的對象分離開。舉個例子,使用者介面可以作為一個觀察者,業務資料是被觀察者,使用者介面觀察業務資料的變化,發現資料變化後,就顯示在介面上。物件導向設計的一個原則是:系統中的每個類別將重點放在某一個功能上,而不是其他方面。一個物件只做一件事情,並且將他做好。觀察者模式在模組之間劃定了清晰的界限,提高了應用程式的可維護性和重用性。
觀察者設計模式定義了物件間的一種一對多的依賴關係,以便當一個物件的狀態發生變化時,所有依賴它的物件都會被通知並自動刷新。
實現方式
觀察者模式有很多實現方式,從根本上說,該模式必須包含兩個角色:觀察者和被觀察對象。在PHP中,使用SplSubject和SplObserver介面來實作觀察者模式。
SplSubject 被觀察對象
SplSubject { /* 方法 */ abstract public void attach ( SplObserver $observer ) //将被观察对象注册到观察者中 abstract public void detach ( SplObserver $observer ) //被观察对账取消注册 abstract public void notify ( void ) //通知所有观察者 }
SplObserver 觀察者
SplObserver { /* 方法 */ abstract public void update ( SplSubject $subject ) //观察者接受到通知的时候,作出相应改变 }
UML類圖
UML類圖
並且向使用者發送一封郵件。使用觀察者程式碼來實現:
function _main() { $user = new User('zhibin','zhibin'); $user->attach(new UserDatabase()); $user->attach(new UserMail()); $user->notify(); } class User implements SplSubject { /** * 帐号 * @var string */ private $_user_name; /** * 密码 * @var string */ private $_password; /** * 观察者列表 * @var array */ private $_observers; public function __construct($user_name,$password) { $this->_user_name = $user_name; $this->_password = $password; $this->_observers = array(); } public function attach(SplObserver $obs) { array_push($this->_observers,$obs); } public function detach(SplObserver $obs) { if($key = array_search($obs,$this->_observers,true)) { unset($this->_observers[$key]); } } public function notify() { foreach($this->_observers as $obs) { $obs->update($this); } } } class UserDatabase implements SplObserver { public function update(SplSubject $sub) { //update database echo 'update database'.PHP_EOL; } } class UserMail implements SplObserver { public function update(SplSubject $sub) { //send mail to user echo 'send mail to user'.PHP_EOL; } } _main();