設計模式九 觀察者模式

0、基本定義

定義對象間一種一對多的依賴關係,使得每當一個對象改變狀態,則全部依賴於它的對象都會獲得通知並被自動更新。ide

發佈者/訂閱者模式。this

 

事件監聽、swing中都有用到。spa

一、代碼實戰

時間核心類日誌

/**
 * 事件
 * @author zzf
 * @date 2018/9/2 15:30.
 */
public class Event {

    //source
    private Object source;
    //target
    private Object target;
    //callback
    private Method callback;

    //觸發事件
    private String trigger;

    private long timestamp;

    public Event(Object target, Method callback) {
        this.target = target;
        this.callback = callback;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    public Method getCallback() {
        return callback;
    }

    public void setCallback(Method callback) {
        this.callback = callback;
    }

    public Object getSource() {
        return source;
    }

    public void setSource(Object source) {
        this.source = source;
    }

    public String getTrigger() {
        return trigger;
    }

    Event setTrigger(String trigger) {
        this.trigger = trigger;
        return this;
    }

    @Override
    public String toString() {
        return "Event{" +
                "source=" + source +
                ", target=" + target +
                ", callback=" + callback +
                ", trigger='" + trigger + '\'' +
                '}';
    }
}
public class EventListener {

    //至關注冊器
    protected Map<Enum, Event> events = new HashMap<>();

    public void addListener(Enum eventType, Object taget, Method callback)  {
        //註冊事件
        //反射調用
        events.put(eventType, new Event(taget, callback));

    }

    private void trigger(Event e) {
        e.setSource(this);
        e.setTimestamp(System.currentTimeMillis());

        try {

            e.getCallback().invoke(e.getTarget(), e);
        } catch (Exception e1) {

        }
    }

    protected void trigger(Enum call) {
        if (!this.events.containsKey(call)) {
            return;
        }

        trigger(this.events.get(call).setTrigger(call.toString()));
     }
}

 

觀察者code

/**
 * 觀察者
 * @author zzf
 * @date 2018/9/2 15:29.
 */
public class Observer {

    public void advice(Event event) {
        System.out.println("====== 觸發事件,打印日誌====\n" + event);
    }
}

被觀察者視頻

/**
 * 被觀察者
 * @author zzf
 * @date 2018/9/2 15:28.
 */
public class Subject extends EventListener {

    //一般採用動態裏實現監控,避免代碼侵入
    public void add() {
        System.out.println("add()");
        trigger(SubjectEventType.ON_ADD);
    }

    public void remove() {
        System.out.println("remove()");
        trigger(SubjectEventType.ON_RMOVE);
    }
}

public enum SubjectEventType {
ON_ADD,
ON_RMOVE,
ON_EDIT,
ON_QUERY;
}
 

testserver

public class ObserverTest {

    public static void main(String[] args) {

        try {

            //觀察者和被觀察者沒有必然的聯繫
            //註冊的時候,才產生聯繫
            Observer observer = new Observer();
            Method advice = Observer.class.getMethod("advice", new Class[]{Event.class});


            Subject subject = new Subject();

            //添加監聽
            subject.addListener(SubjectEventType.ON_ADD, observer, advice);

            subject.add();
            subject.remove();

        } catch (Exception e) {

        }
    }
}

 

二、使用場景

》關聯行爲場景對象

》事件多級觸發場景blog

》跨系統的消息交換場景,如消息隊列的處理機制。隊列

三、總結

這是聽咕泡學院視頻的實戰筆記。和書上的標準模式demo 相差仍是蠻大的。

 

本身感受能看懂,可是在實際中應用仍是有點懵。

 

參考資料:

咕泡學院

相關文章
相關標籤/搜索