拿一個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();
}
}
}