设计模式之观察者模式(java实现)
观察者模式(Observer):一种行为型的设计模式,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
在Spring中,观察者模式常用的地方是Listener的实现,如ApplicationListener。
它一般由两个角色组成:发布者和订阅者(观察者)。观察者通常有一个回调,当然也可以没有。
在实际的工作中,监听器,日志收集,短信通知,邮件通知这些业务逻辑中可以考虑用到观察者模式。
下面以监听器来举例,在前端开发中,不管是js里面的click()时间,还是移动端app开发中的各种监听事件的捕获,都有用到观察者模式。
先来一个比较容易理解的实际例子。鼠标(Mouse)时间的监听,鼠标操作有单击(Click),双击(DoubleClick),移动(Move),悬停(Over),滚动(Wheel),弹起(Up),按下(Down)。
类图:
Event类定义了事件的机制:
package Observer.core;
import java.lang.reflect.Method;
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;
}
Event setSource(Object source) {
this.source = source;
return this;
}
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;
}
Event setTrigger(String trigger) {
this.trigger = trigger;
return this;
}
public Long getTime() {
return time;
}
Event setTime(Long time) {
this.time = time;
return this;
}
@Override
public String toString() {
return "Event{" +
"\n\tsource=" + source + ",\n" +
"\ttarget=" + target + ",\n" +
"\tcallback=" + callback + ",\n" +
"\ttrigger='" + trigger + '\'' + "\n" +
'}';
}
}
EventListener类,是事件的注册和监听类,有一个Map相当于注册器,目的是存放各种触发的事件和相对应的条件。一般在观察者模式中都需要一个注册器。
package Observer.core;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* 事件的注册和监听
*/
public class EventListener {
//注册器
protected Map<Enum,Event> events = new HashMap<Enum,Event>();
public void addListener(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()));
}
}
Mouse类:被观察者,继承于Eventlistener,定义了鼠标各种操作时候的情况:
package Observer.mouse;
import Observer.core.EventListener;
/**
* 被观察者
*/
public class Mouse extends EventListener {
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);
}
}
MouseEventType:枚举,里面存储mouse各种操作定义:
package Observer.mouse;
public enum MouseEventType {
ON_CLICK,
ON_DOUBLE_CLICK,
ON_UP,
ON_DOWN,
ON_WHEEL,
ON_MOVE,
ON_OVER;
}
MouseEventCallback:观察者,回调响应的逻辑。
package Observer.mouse;
import Observer.core.Event;
/**
* 回调响应的逻辑
* 观察者
*/
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);
}
}
测试类:
package Observer.mouse;
import Observer.core.Event;
import java.lang.reflect.Method;
public class MouseTest {
public static void main(String[] args) {
try {
Mouse mouse = new Mouse();
MouseEventCallBack mouseEventCallBack = new MouseEventCallBack();
//方法定义
Method onClick = MouseEventCallBack.class.getMethod("onClick", Event.class);
Method onDoubleClick = MouseEventCallBack.class.getMethod("onDoubleClick", Event.class);
Method onUp = MouseEventCallBack.class.getMethod("onUp", Event.class);
Method onDown = MouseEventCallBack.class.getMethod("onDown", Event.class);
Method onWheel = MouseEventCallBack.class.getMethod("onWheel", Event.class);
Method onOver = MouseEventCallBack.class.getMethod("onOver", Event.class);
Method onMove = MouseEventCallBack.class.getMethod("onMove", Event.class);
//加入监听
mouse.addListener(MouseEventType.ON_CLICK,mouseEventCallBack,onClick);
mouse.addListener(MouseEventType.ON_DOUBLE_CLICK,mouseEventCallBack,onDoubleClick);
mouse.addListener(MouseEventType.ON_UP,mouseEventCallBack,onUp);
mouse.addListener(MouseEventType.ON_DOWN,mouseEventCallBack,onDown);
mouse.addListener(MouseEventType.ON_WHEEL,mouseEventCallBack,onWheel);
mouse.addListener(MouseEventType.ON_OVER,mouseEventCallBack,onOver);
mouse.addListener(MouseEventType.ON_MOVE,mouseEventCallBack,onMove);
//被观察者执行相对应的动作
mouse.click();
mouse.doubleClick();
mouse.up();
mouse.down();
mouse.wheel();
mouse.over();
mouse.move();
}catch (Exception e){
e.printStackTrace();
}
}
}
执行测试类输出结果:
可以看到,当对应的方法加入监听中之后,被观察者执行了什么操作,观察者也就有了对应的处理。
还没有评论,来说两句吧...