## 定义
    在对象之间定义一种一对多依赖关系，当一个对象状态改变的时候，所有依赖的对象都会得到通知并被自动更新。

## 设计的原则和思想
1. 解耦观察者和被观察者。
2. 不变部分是观察者和被观察者的关联，变化部分是观察者和被观察者。
3. 核心思想是对象之间一对多的关联关系。

## 一句话概括设计模式
    被观察者的操作，观察者都能监控。

## 结构中包含的角色
1. Subject（目标）
2. ConcreteSubject（具体目标）
3. Observer（观察者）
4. 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();

## 优点
1. 观察目标和观察者之间建立了一个抽象的耦合。观察目标只需要维持一个抽象观察者的集合，无须了解其具体观察者。
2. 观察者模式的广播通信机制，简化了一对多系统设计的难度。
3. 增加新的具体观察者和新的观察目标都很方便，无须修改原有系统代码。
4. 运行时才建立观察者和被观察者之间的联系。
5. 观察者和被观察者可以各自独立地改变和复用。观察者模式中的目标和观察者的变化不是独立的，而是有着某些关联。

## 缺点
1. 如果有很多观察者，通知会花很多时间。
2. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的，而仅仅只是知道观察目标发生了变化。
3. 订阅者的通知顺序是随机的。

## 何时使用
1. 一个抽象模型有两个方面，其中一个方面依赖于另一个方面，将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用。
2. 一个对象的改变将导致一个或多个其他对象也发生改变。
3. 需要在系统中创建一个触发链，可以使用观察者模式创建一种链式触发机制。

## 实际应用场景
1. Laravel的事件。 
2. 异步回调。
3. EventBus事件总线。
4. 广播通知。