觀察者模式:又叫發佈-訂閱模式,這裏面有兩個最重要的元素,一個是觀察者,一個是被觀察者,觀察者的行爲依賴於被觀察者的狀態,或者說當被觀察對象(事件源對象)的狀態改變時,會影響到觀察者的行爲。UML圖以下:
其中,Source類是被觀察者,它把全部對觀察者對象的引用文件存在了一個集合,每一個被觀察者均可以有任何數量的觀察者。Observer類是抽象觀察者,爲全部的具體觀察者定義一個接口,在獲得被觀察者的通知時作出相應的操做;當Source內部的狀態發生改變時,給全部登記過的觀察者發出通知(傳入一個event,也就是將狀態變化封裝爲一個事件);Observer1和Observer2具體觀察者實現抽象觀察者角色所要求的行爲,以便使自己的狀態與被觀察者的狀態相協同javascript
關聯行爲場景
事件多級觸發場景java
在這裏,我使用一個畢竟簡單的例子介紹一下,好比java awt中的事件,當窗口上的按鈕被點擊的時候,事件監聽器打印相應的內容,在這個當中,咱們模仿一下awt的事件機制:數組
首先定義一個觀察者數組,並實現增、刪及通知操做。它的職責很簡單,就是定義誰能觀察,誰不能觀察ide
class Button{ private List<ActionListener> actionListeners = new ArrayList<>(); //當按鈕被按下,通知觀察者,傳入事件對象,觀察者作出相應的操做 public void buttonPressed(){ ActionEvent e = new ActionEvent(System.currentTimeMillis(), this); for(int i = 0; i< actionListeners.size(); i++) { actionListeners.get(i).actionPerformed(e); } } public void addActionListerner(ActionListener listener){ actionListeners.add(listener); } public void delActionListerner(ActionListener listener){ actionListeners.remove(listener); } }
觀察者通常是一個接口,每個實現該接口的實現類都是具體觀察者ui
interface ActionListener { public void actionPerformed(ActionEvent e); }
這裏解釋一下爲何定義一個事件對象,有時候咱們可能只是簡單的通知一下觀察者,不須要傳太多東西,可是大部分時候可能咱們的觀察者還須要知道更多的東西,好比事件源,若是咱們的觀察者須要調用被觀察者的方法,那麼咱們在這個事件對象當中拿到被觀察者對象,就能夠直接調用它的方法了this
class ActionEvent{ long when; Object source; public ActionEvent(long when, Object source){ super(); this.when = when; this.source = source; } public long getWhen() { return when; } public Object getSource() { return source; } }
class MyActionListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("button pressed!"); } } class MyActionListener2 implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("button pressed 2!"); } }
public class Test { public static void main(String[] args) { //事件源對象/被觀察者 Button button = new Button(); //觀察 button.addActionListerner(new MyActionListener()); button.addActionListerner(new MyActionListener2()); //開始活動 button.buttonPressed(); } }
總結:觀察者模式的應用比較普遍,在這種ui上面的事件機制,如awt,javascript的按鈕點擊事件等,它還能夠跟責任鏈模式結合使用,將具體的觀察者串成一條鏈,接收到通知的時候在鏈中去執行spa
Observer、Listener、Hook、Callback全都是觀察者模式code