观察者模式应用场景:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变,所有依赖与他的对象都能得到通知并被自动更新。
Spring中Observer模式中常用的地方是Listener的实现,如:ApplicationListener
图示:
代码演示:
package com.gupaoedu.observer;
/**
* ClassName:SubjectEventType
* PackageName:com.gupaoedu.observer
* Description:
*
* @date:2020/7/23 21:43
* @author:robin
*/
public enum SubjectEventType {
//定义四个事件
ON_ADD,
ON_REMOVE,
ON_EDIT,
ON_QUERY;
}
package com.gupaoedu.observer;
/**
* ClassName:Observer
* PackageName:com.gupaoedu.observer
* Description:
* 你每做一件事情,我都观察到你,我做些事情,比如打印日志
*举例:比如老师观察学生,只要学生上课吃辣条,老师就通知家长。
*
*
* 观察者
* @date:2020/7/23 20:33
* @author:robin
*/
public class Observer {
/**
* 通知方法
* @param e
*/
public void advice(Event e){
System.out.println("============触发事件,打印日志========="+"\n"+e);
}
/**
* input.addListener("click",function(){
*
* })
*
*
*/
}
package com.gupaoedu.observer;
import java.lang.reflect.Method;
/**
* ClassName:Event
* PackageName:com.gupaoedu.observer
* Description:
*事件类
* @date:2020/7/23 20:38
* @author:robin
*/
public class Event {
//事件源
private Object source;
//通知目标类
private Object target;
//回调
private Method callback;
//事件生成时间
private long time;
//触发
private String trigger;
public Object getSource() {
return source;
}
void setSource(Object source) {
this.source = source;
}
public Object getTarget() {
return target;
}
Event setTarget(Object target) {
this.target = target;
//链式编程
return this;
}
public Method getCallback() {
return callback;
}
public void setCallback(Method callback) {
this.callback = callback;
}
public String getTrigger() {
return trigger;
}
public long getTime() {
return time;
}
//默认的访问权限,只能在同一个包下面使用
Event setTime(long time) {
this.time = time;
//链式编程
return this;
}
Event setTrigger(String trigger) {
this.trigger = trigger;
//链式编程
return this;
}
public Event(Object target, Method callback) {
// this.source = source;
this.target = target;
this.callback = callback;
// this.trigger = trigger;
}
@Override
public String toString() {
return "Event{" +
"source=" + source +
", target=" + target +
", callback=" + callback +
", trigger='" + trigger + '\'' +
'}';
}
}
package com.gupaoedu.observer;
import java.lang.reflect.Method;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
/**
* ClassName:EventListener
* PackageName:com.gupaoedu.observer
* Description:
*注册器 类
*
* @date:2020/7/23 20:47
* @author:robin
*/
public class EventListener {
protected Map<Enum,Event> events=new HashMap<Enum, Event>();
/**
* input.addListener("click",function(){
*
* })
* @param event
* @param target
* @param callback
*
* 注册事件的方法
*/
public void addListener(Enum event, Object target, Method callback){
//用反射调用这个对象
events.put(event,new Event(target,callback));
}
/**
* 触发事件的方法
* @param e
*/
private void trigger(Event e){
e.setSource(this);
e.setTime(System.currentTimeMillis());
try{
//调用观察者 advice(Event e)
Method m = e.getCallback();
m.invoke(e.getTarget(),e);
}catch (Exception e1){
e1.printStackTrace();
}
}
/**
* 触发事件
* @param call
*/
protected void trigger(Enum call){
if (!this.events.containsKey(call)){return;}
//触发内部的方法
//this.events.get(call).setTrigger(call.toString()) 返回Event
trigger(this.events.get(call).setTrigger(call.toString()));
}
}
package com.gupaoedu.observer;
/**
* ClassName:Subject
* PackageName:com.gupaoedu.observer
* Description:
*被观察者
* @date:2020/7/23 17:50
* @author:robin
* 让观察者与被观察者关联起来
* 继承事件注册器
*/
public class Subject extends EventListener {
//通常的话这里采用动态代理实现,避免了代码的侵入。
public void add(){
System.out.println("调用添加的方法");
//触发方法(默认不执行,当被观察者注册事件subject.addListener()后才执行)
trigger(SubjectEventType.ON_ADD);
}
public void remove(){
System.out.println("调用删除的方法");
//触发方法
trigger(SubjectEventType.ON_REMOVE);
}
}
package com.gupaoedu.observer;
import java.lang.reflect.Method;
/**
* ClassName:ObserverTest
* PackageName:com.gupaoedu.observer
* Description:
*
* @date:2020/7/23 21:46
* @author:robin
*/
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();
/**
* public void addListener(Enum event,
* Object target,
* Method callback)
*/
subject.addListener(SubjectEventType.ON_ADD,observer,advice);
subject.add(); //注释掉了之后,上面监听方法(注册方法)不起效。
//结论: 被观察者做事,观察者就做事。
/**
*
* 输出结果
*
* 调用添加的方法
* ============触发事件,打印日志=========
* Event{source=com.gupaoedu.observer.Subject@14ae5a5, target=com.gupaoedu.observer.Observer@7f31245a, callback=public void com.gupaoedu.observer.Observer.advice(com.gupaoedu.observer.Event), trigger='ON_ADD'}
*/
}catch (Exception e){
e.printStackTrace();
}
}
}