觀察者模式 (observer Pattern): 定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。也叫發佈-訂閱模式
(一)爲什麼需要觀察者模式
1,一個對象狀態改變給其他對象通知的問題,而且要考慮到易用和低耦合,保證高度的協作
2,完美的將觀察者和被觀察的對象分離開,使得每個類將重點放在某一個功能上,一個對象只做一件事情。
3,觀察者模式在模塊之間劃定了清晰的界限,提高了應用程序的可維護性和重用性
(二)觀察者模式 UML圖
這個設計模式的UML圖比較全
(三)簡單實例
觀察者模式也叫發佈訂閱模式,如果說我們現在在做一個系統。我們讓所有客戶端訂閱我們的服務端,那麼當我們的服務端有更新信息的時候,就通知客戶端去更新。這裏的服務端就是被觀察者,客戶端就是觀察者。
對於PHP來說觀察者的另一種實現方式,是通過實現SplSubject接口和SplObserver,這種實現方法涉及到spl(standard php library)的內容,這裏僅僅演示如何實現,具體的大家可以自行google||百度。
abstract class Entity{
private $observers = [];
public function add($observer)
{
// 注意 直接把對象作爲字符串輸出的話,會調用魔術方法__toString
$this->observers[] = $observer;
echo sprintf("%s觀察者添加成功!<br/>", $observer);
}
public function delete($observer)
{
$key = array_search($observer, $this->observers);
// 對象存在但是不一定是同一個對象,所以需要 === 判斷一下
if ($observer === $this->observers[$key]){
unset($this->observers[$key]);
echo sprintf("觀察者刪除成功!<br/>");
}else{
echo sprintf("觀察者不存在!<br/>");
}
}
public function notifyObserver()
{
foreach ($this->observers as $observer){
$observer->save();
}
}
}
class server extends Entity{
public function publish()
{
echo sprintf("618就要到了,活動福利多多請關注<br/>");
$this->notifyObserver();
}
}
Interface Observer{
public function save();
}
class Wechat implements Observer{
public function save()
{
echo sprintf("%s已經發送了!<br/>", __CLASS__);
}
// object to string 時調用
public function __toString()
{
return __CLASS__;
}
}
class Android implements Observer{
public function save()
{
echo sprintf("%s已經發送了!<br/>", __CLASS__);
}
// object to string 時調用
public function __toString()
{
return __CLASS__;
}
}
class Ios implements Observer{
public function save()
{
echo sprintf("%s已經發送了!<br/>", __CLASS__);
}
// object to string 時調用
public function __toString()
{
return __CLASS__;
}
}
// 實例化被觀察者
$entity = new Server();
// 註冊微信
$entity->add(new Wechat());
// 註冊安卓
$entity->add(new Android());
$ios = new Ios();
// 註冊IOS
$entity->add($ios);
// 觸發時間,發送消息
$entity->publish();
//輸出信息如下
//Wechat觀察者添加成功!
//Android觀察者添加成功!
//Ios觀察者添加成功!
//618就要到了,活動福利多多請關注
//Wechat已經發送了!
//Android已經發送了!
//Ios已經發送了!
// 新實例化IOS 然後刪除IOS
$entity->delete(new Ios()); // 會提示 觀察者不存在!
// 再次發消息
$entity->publish();
// 刪除IOS
$entity->delete($ios);
// 再次發消息
$entity->publish();
//輸出信息如下
// ………………
//觀察者刪除成功!
//618就要到了,活動福利多多請關注
//Wechat已經發送了!
//Android已經發送了!
參考資料: