观察者模式(Observer)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
Spring中Observer模式常用的地方是Listener的实现,如ApplicationListener
观察者模式是一种行为型模式,一般有2个角色组成,发布者和订阅者(观察者),观察者通常有一个回调,也可以没有
代码实现
设计一个动作,鼠标点击之后,监听鼠标点击的事件也会被执行
鼠标类
public class Mouse extends EventLisenter{
public void click(){
System.out.println("鼠标单击");
this.trigger(MouseEventType.ON_CLICK);
}
public void doubleClick(){
System.out.println("鼠标双击");
this.trigger(MouseEventType.ON_DOUBLE_CLICK);
}
public void up(){
System.out.println("鼠标弹起");
this.trigger(MouseEventType.ON_UP);
}
public void down(){
System.out.println("鼠标按下");
this.trigger(MouseEventType.ON_DOWN);
}
public void wheel(){
System.out.println("鼠标滚动");
this.trigger(MouseEventType.ON_WHEEL);
}
public void move(){
System.out.println("鼠标移动");
this.trigger(MouseEventType.ON_MOVE);
}
public void over(){
System.out.println("鼠标悬停");
this.trigger(MouseEventType.ON_OVER);
}
//鼠标触发类
public class MouseEventCallback {
public void onClick(Event e){
System.out.println("这是鼠标单击以后要执行的逻辑");
System.out.println("=======触发鼠标单击事件========\n" + e);
}
public void onDoubleClick(Event e){
System.out.println("=======触发鼠标双击事件========\n" + e);
}
public void onUp(Event e){
System.out.println("=======触发鼠标弹起事件========\n" + e);
}
public void onDown(Event e){
System.out.println("=======触发鼠标按下事件========\n" + e);
}
public void onMove(Event e){
System.out.println("=======触发鼠标移动事件========\n" + e);
}
public void onWheel(Event e){
System.out.println("=======触发鼠标滚动事件========\n" + e);
}
public void onOver(Event e){
System.out.println("=======触发鼠标悬停事件========\n" + e);
}
}
//鼠标枚举类
public enum MouseEventType {
ON_CLICK,
ON_DOUBLE_CLICK,
ON_UP,
ON_DOWN,
ON_WHEEL,
ON_MOVE,
ON_OVER;
}
//观察事件类
public class Event {
//事件源
private Object source;
//通知目标
private Object target;
//回调
private Method callback;
//触发
private String trigger;
private long time;
public Event(Object target, Method callback) {
this.target = target;
this.callback = callback;
}
public Object getSource() {
return source;
}
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 String getTrigger() {
return trigger;
}
@Override
public String toString() {
return "Event{" +
"\n\tsource=" + source + ",\n" +
"\ttarget=" + target + ",\n" +
"\tcallback=" + callback + ",\n" +
"\ttrigger='" + trigger + '\'' + "\n" +
'}';
}
public long getTime() {
return time;
}
Event setTime(long time) {
this.time = time;
return this;
}
Event setSource(Object source) {
this.source = source;
return this;
}
Event setTrigger(String trigger) {
this.trigger = trigger;
return this;
}
}
//事件的注册和监听
public class EventLisenter {
//Map相当于是一个注册器
protected Map<Enum,Event> events = new HashMap<Enum,Event>();
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()));
}
}
测试
public class MouseTest {
public static void main(String[] args) {
/*
* var input = document.getElementById("username");
* input.addLisenter("click",function(){
*
* alert("鼠标点击了这个文本框");
*
* });
*
*
* */
//观察者和被观察者之间没有必然联系
//注册的时候,才产生联系
//解耦
try {
MouseEventCallback callback = new MouseEventCallback();
Method onClick = MouseEventCallback.class.getMethod("onClick", Event.class);
//人为的调用鼠标的单击事件
Mouse mouse = new Mouse();
mouse.addLisenter(MouseEventType.ON_CLICK, callback,onClick);
mouse.click();
}catch (Exception e){
e.printStackTrace();
}
}
}
测试结果
鼠标单击
这是鼠标单击以后要执行的逻辑
=触发鼠标单击事件==
Event{
source=gupaoedu.vip.pattern.observer.mouse.Mouse@14ae5a5,
target=gupaoedu.vip.pattern.observer.mouse.MouseEventCallback@7f31245a,
callback=public void gupaoedu.vip.pattern.observer.mouse.MouseEventCallback.onClick(gupaoedu.vip.pattern.observer.core.Event),
trigger=‘ON_CLICK’
}