觀察者模式

拿一個listener舉例,subject是被觀察的對象,Observer是觀察者
event是事件,EventLisenter是事件注冊和監(jiān)聽。

事件類的代碼如下:

public class Event {

    //事件源
    private Object source;
    //通知目標
    private Object target;
    //回調
    private Method callback;
    //觸發(fā)
    private String trigger;

    private long time;

    public Event(Object target, Method callback) {
        this.target = target;
        this.callback = callback;
    }
 //此處省去set get方法
}

事件類型枚舉

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

EventLisenter類

/**
 * 事件的注冊和監(jiān)聽
 */
public class EventLisenter {

    //Map相當于是一個注冊器,什么事件觸發(fā)什么方法放入該容器內(nèi)
    protected Map<Enum,Event> events = new HashMap<Enum,Event>();

    
    //參數(shù)說明:1.什么事情;2.觀察者是誰;3.調用觀察者的什么方法
    public void addLisenter(Enum eventType,Object target,Method callback){
        //注冊事件
        //用反射調用這個方法
        events.put(eventType,new Event(target,callback));
    }
 
    private void trigger(Event e){
        e.setSource(this);
        e.setTime(System.currentTimeMillis());
        try {
            e.getCallback().invoke(e.getTarget(),e);
            
        } catch (Exception e1) {
            e1.printStackTrace();
        } 
    }


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

被觀察的類subject(繼承時間監(jiān)聽類,并在自己的方法里,加入事件觸發(fā)的方法):

public class Subject extends EventLisenter{

    //通常的話,采用動態(tài)里來實現(xiàn)監(jiān)控,避免了代碼侵入
    public void add(){
        System.out.println("調用添加的方法");
        trigger(SubjectEventType.ON_ADD);
    }

    public void remove(){
        System.out.println("調用刪除的方法");
        trigger(SubjectEventType.ON_RMOVE);
    }

}

客戶端測試類:

public class ObserverTest {

    public static void main(String[] args) {

        try{

            //觀察者
            Observer observer = new Observer();
            Method advice = Observer.class.getMethod("advice", new Class<?>[]{Event.class});


            //創(chuàng)建被觀察者
            Subject subject = new Subject();
            //添加事件
            subject.addLisenter(SubjectEventType.ON_ADD,observer,advice);
            subject.addLisenter(SubjectEventType.ON_EDIT,observer,advice);
            subject.addLisenter(SubjectEventType.ON_RMOVE,observer,advice);
            subject.addLisenter(SubjectEventType.ON_QUERY,observer,advice);
            //調用下面的方法,觀察者會調用之前添加的事件
            subject.add();
            subject.remove();
        }catch (Exception e){
            e.printStackTrace();
        }

    }

}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容