設計模式-觀察者模式

Root發表於2017-03-10

可進入我的部落格檢視原文。

定義

觀察者模式定義了物件之間的一對多依賴,使得當一個物件改變狀態時,它的所有依賴者都會收到通知並自動更新。觀察者模式又叫釋出/訂閱模式

角色

  • 抽象主題(Subject):它把所有觀察者物件的引用儲存到一個列表裡,每個主題都可以有任何數量的觀察者。抽象主題提供一個介面,可以增加和刪除觀察者物件。

  • 具體主題(ConcreteSubject):將有關狀態存入具體觀察者物件;在具體主題內部狀態改變時,給所有登記過的觀察者發出通知。

  • 抽象觀察者(Observer):為所有的具體觀察者定義一個介面,在得到主題通知時更新自己。

  • 具體觀察者(ConcreteObserver):實現抽象觀察者角色所要求的更新介面,以便使本身的狀態與主題狀態協調。

類圖

設計模式-觀察者模式
觀察者模式

示例

獵頭-求職者為例。獵頭是主題,求職者是觀察者。

Subject 介面

public interface Subject {
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyAllObservers();
}複製程式碼

Observer 介面

public interface Observer {
    public void update(Subject s);
}複製程式碼

HeadHunter 類實現 Subject 介面

import java.util.LinkedList;

public class HeadHunter implements Subject {
    private LinkedList<Observer> userList;
    private LinkedList<String> jobs;

    public HeadHunter() {
        userList = new LinkedList<Observer>();
        jobs = new LinkedList<String>();
    }

    @Override
    public void registerObserver(Observer o) {
        userList.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        userList.remove(o);
    }

    @Override
    public void notifyAllObservers() {
        for (Observer o: userList) {
            o.update(this);
        }
    }

    public void addJob(String job) {
        jobs.add(job);
        notifyAllObservers();
    }

    public LinkedList<String> getJobs() {
        return jobs;
    }

    public String toString() {
        return jobs.toString();
    }
}複製程式碼

JobSeeker 類實現 Observer 介面

public class JobSeeker implements Observer {
        private String name;

        public JobSeeker(String name) {
            this.name = name;
        }

        @Override
        public void update(Subject s) {
            System.out.println(this.name + " got notified!");
            System.out.println(s);
        }
}複製程式碼

測試

public class Main {
    public static void main(String[] args) {
        HeadHunter hh = new HeadHunter();

        JobSeeker lbd = new JobSeeker("lbd");
        JobSeeker lbx = new JobSeeker("lbx");
        JobSeeker lbn = new JobSeeker("lbn");
        JobSeeker lbb = new JobSeeker("lbb");

        hh.registerObserver(lbd);
        hh.registerObserver(lbx);
        hh.registerObserver(lbn);
        hh.registerObserver(lbb);
        hh.removeObserver(lbb);

        hh.addJob("looking for Java engineers");
        hh.addJob("looking for Python engineers");
    }
}複製程式碼

輸出

lbd got notified!
[looking for Java engineers]
lbx got notified!
[looking for Java engineers]
lbn got notified!
[looking for Java engineers]
lbd got notified!
[looking for Java engineers, looking for Python engineers]
lbx got notified!
[looking for Java engineers, looking for Python engineers]
lbn got notified!
[looking for Java engineers, looking for Python engineers]複製程式碼

總結

觀察者模式使主題和觀察者之間鬆耦合,鬆耦合的設計能夠讓我們建立有彈性的OO系統,能夠應對變化,因為物件直接的相互依賴降到了最低。

其他

  • 上面的例子是觀察者模式的“推”模式,還有一種“拉”模式。
  • Java 的 java.util 庫裡面,提供了一個 Observable 類以及一個 Observer 介面,構成 Java 語言對觀察者模式的支援。

可進入我的部落格檢視原文。

相關文章