OBSERVER(觀察者) —對象行爲型模式

觀察者模式

  • 什麼是觀察者模式
    定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使他們能夠自動更新自己.別名依賴(Dependents), 發佈-訂閱( publish - subscribe)

  • 什麼場景會用到命令模式
    一個對象的改變需要同時改變其它對象的時候,而且不知道具體有多少個對象有待改變時。想想以前的報紙訂閱,如果我們定了人名日報,每到早上都會有送報的上門,不管你愛看不愛看這陣子的新聞,只要報紙一出版就會很快送達,如果訂閱者最近沒有時間看新聞來, 只要取消訂閱,接下來新出版的報紙就不會再送了。
    我們擬定一個場景,辦公室的所有人都無所事事,程序員,PO和TEAMLEADER,但是當然大家都怕老闆過來查崗,所以就需要一個類似哨兵的幫忙來監視老闆的行徑,這時候前臺就起到很大的作用了,當老闆回來的時候肯定先經過前臺,這時候前臺再去通知所有人,告訴大家該做正經事了。

public interface Employee {
    void update();
}
public interface Action {
   void action();
}
public class Developer implements Employee, Action {

    @Override
    public void action() {
        System.out.println("coding");
    }

    @Override
    public void update() {
        action();
    }
}
public class ProductManager implements Employee, Action {

    @Override
    public void action() {
        System.out.println("discuss requirements");
    }

    @Override
    public void update() {
        action();
    }
}
public class TeamLeader implements Employee, Action {

    @Override
    public void action() {
        System.out.println("writing document");
    }

    @Override
    public void update() {
        action();
    }
}

前臺

public class Receptionist implements Employee{

    List<Employee> employees = new ArrayList<>();


    public void addEmployee(Employee employee) {
        employees.add(employee);
    }

    public void cancelEmployee(Employee employee) {
        Objects.requireNonNull(employees);

        employees.remove(employee);
    }

    @Override
    public void update() {
        System.out.println("boss is coming");
        notifyEmployees();
    }

    private void notifyEmployees() {
        employees.forEach(Employee::update);
    }

}

測試如下

public static void main(String[] args) {

        Receptionist receptionist = new Receptionist();

        receptionist.addEmployee(new Developer());
        receptionist.addEmployee(new ProductManager());
        Employee teamLeader = new TeamLeader();
        receptionist.addEmployee(teamLeader);
        receptionist.cancelEmployee(teamLeader);

        receptionist.update();

    }
  • 適用性
    -在以下任一情況下可以使用觀察者模式 :
    • 當一個抽象模型有兩個方面 , 其中一個方面依賴於另一方面。將這二者封裝在獨立的對
    象中以使它們可以各自獨立地改變和複用。
    • 當對一個對象的改變需要同時改變其它對象 , 而不知道具體有多少對象有待改變。
    • 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之 , 你不希望這些
    對象是緊密耦合的。

    JDK裏面內置了觀察者模式的功能,在java.util包內的Observer接口和Observable類,基本上實現類似,就不一一講解了。有興趣的大家可以去查看它的源碼。

相關參考:
<大話設計模式>,<設計模式,可複用面向對象軟件的基礎>,<Head First 設計模式>
源碼在此

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章