定義
在物件之間定義一種一對多依賴關係,當一個物件狀態改變的時候,所有依賴的物件都會得到通知並被自動更新。
設計的原則和思想
- 解耦觀察者和被觀察者。
- 不變部分是觀察者和被觀察者的關聯,變化部分是觀察者和被觀察者。
- 核心思想是物件之間一對多的關聯關係。
一句話概括設計模式
被觀察者的操作,觀察者都能監控。
結構中包含的角色
- Subject(目標)
- ConcreteSubject(具體目標)
- Observer(觀察者)
- ConcreteObserver(具體觀察者)
最小可表達程式碼
abstract class Subject
{
protected $observers = [];
public abstract function notify();
public function add(Observer $observer)
{
$this->observers[] = $observer;
}
}
class ConcreteSubject extends Subject
{
public function notify()
{
foreach ($this->observers as $observer) {
$observer->update();
}
}
}
interface Observer {
public function update();
}
class ConcreteObserver implements Observer
{
public function update()
{
echo '觀察者更新';
}
}
$subject = new ConcreteSubject();
$subject->add(new ConcreteObserver());
$subject->notify();
優點
- 觀察目標和觀察者之間建立了一個抽象的耦合。觀察目標只需要維持一個抽象觀察者的集合,無須瞭解其具體觀察者。
- 觀察者模式的廣播通訊機制,簡化了一對多系統設計的難度。
- 增加新的具體觀察者和新的觀察目標都很方便,無須修改原有系統程式碼。
- 執行時才建立觀察者和被觀察者之間的聯絡。
- 觀察者和被觀察者可以各自獨立地改變和複用。觀察者模式中的目標和觀察者的變化不是獨立的,而是有著某些關聯。
缺點
- 如果有很多觀察者,通知會花很多時間。
- 觀察者模式沒有相應的機制讓觀察者知道所觀察的目標物件是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。
- 訂閱者的通知順序是隨機的。
何時使用
- 一個抽象模型有兩個方面,其中一個方面依賴於另一個方面,將這兩個方面封裝在獨立的物件中使它們可以各自獨立地改變和複用。
- 一個物件的改變將導致一個或多個其他物件也發生改變。
- 需要在系統中建立一個觸發鏈,可以使用觀察者模式建立一種鏈式觸發機制。
實際應用場景
- Laravel的事件。
- 非同步回撥。
- EventBus事件匯流排。
- 廣播通知。
本作品採用《CC 協議》,轉載必須註明作者和本文連結