设计模式之观察者模式(java实现)

╰半夏微凉° 2022-04-11 11:20 269阅读 0赞

观察者模式(Observer):一种行为型的设计模式,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

在Spring中,观察者模式常用的地方是Listener的实现,如ApplicationListener。

它一般由两个角色组成:发布者和订阅者(观察者)。观察者通常有一个回调,当然也可以没有。

在实际的工作中,监听器,日志收集,短信通知,邮件通知这些业务逻辑中可以考虑用到观察者模式。

下面以监听器来举例,在前端开发中,不管是js里面的click()时间,还是移动端app开发中的各种监听事件的捕获,都有用到观察者模式。

先来一个比较容易理解的实际例子。鼠标(Mouse)时间的监听,鼠标操作有单击(Click),双击(DoubleClick),移动(Move),悬停(Over),滚动(Wheel),弹起(Up),按下(Down)。

类图:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhcnJ5cHR0ZXI_size_16_color_FFFFFF_t_70

Event类定义了事件的机制:

  1. package Observer.core;
  2. import java.lang.reflect.Method;
  3. public class Event {
  4. //事件源
  5. private Object source;
  6. //通知目标
  7. private Object target;
  8. //回调方法
  9. private Method callback;
  10. //触发
  11. private String trigger;
  12. private Long time;
  13. public Event(Object target, Method callback) {
  14. this.target = target;
  15. this.callback = callback;
  16. }
  17. public Object getSource() {
  18. return source;
  19. }
  20. Event setSource(Object source) {
  21. this.source = source;
  22. return this;
  23. }
  24. public Object getTarget() {
  25. return target;
  26. }
  27. public void setTarget(Object target) {
  28. this.target = target;
  29. }
  30. public Method getCallback() {
  31. return callback;
  32. }
  33. public void setCallback(Method callback) {
  34. this.callback = callback;
  35. }
  36. public String getTrigger() {
  37. return trigger;
  38. }
  39. Event setTrigger(String trigger) {
  40. this.trigger = trigger;
  41. return this;
  42. }
  43. public Long getTime() {
  44. return time;
  45. }
  46. Event setTime(Long time) {
  47. this.time = time;
  48. return this;
  49. }
  50. @Override
  51. public String toString() {
  52. return "Event{" +
  53. "\n\tsource=" + source + ",\n" +
  54. "\ttarget=" + target + ",\n" +
  55. "\tcallback=" + callback + ",\n" +
  56. "\ttrigger='" + trigger + '\'' + "\n" +
  57. '}';
  58. }
  59. }

EventListener类,是事件的注册和监听类,有一个Map相当于注册器,目的是存放各种触发的事件和相对应的条件。一般在观察者模式中都需要一个注册器。

  1. package Observer.core;
  2. import java.lang.reflect.Method;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. /**
  6. * 事件的注册和监听
  7. */
  8. public class EventListener {
  9. //注册器
  10. protected Map<Enum,Event> events = new HashMap<Enum,Event>();
  11. public void addListener(Enum eventType, Object target, Method callback){
  12. //注册事件
  13. //用反射调用这个方法
  14. events.put(eventType,new Event(target,callback));
  15. }
  16. private void trigger(Event e){
  17. e.setSource(this);
  18. e.setTime(System.currentTimeMillis());
  19. try {
  20. e.getCallback().invoke(e.getTarget(),e); //使用反射的方法
  21. } catch (Exception e1) {
  22. e1.printStackTrace();
  23. }
  24. }
  25. //当注册器中查到相对应的时间,那么触发回调
  26. protected void trigger(Enum call){
  27. if(!this.events.containsKey(call)){ return ;}
  28. trigger(this.events.get(call).setTrigger(call.toString()));
  29. }
  30. }

Mouse类:被观察者,继承于Eventlistener,定义了鼠标各种操作时候的情况:

  1. package Observer.mouse;
  2. import Observer.core.EventListener;
  3. /**
  4. * 被观察者
  5. */
  6. public class Mouse extends EventListener {
  7. public void click(){
  8. System.out.println("鼠标单击");
  9. this.trigger(MouseEventType.ON_CLICK);
  10. }
  11. public void doubleClick(){
  12. System.out.println("鼠标双击");
  13. this.trigger(MouseEventType.ON_DOUBLE_CLICK);
  14. }
  15. public void up(){
  16. System.out.println("鼠标弹起");
  17. this.trigger(MouseEventType.ON_UP);
  18. }
  19. public void down(){
  20. System.out.println("鼠标按下");
  21. this.trigger(MouseEventType.ON_DOWN);
  22. }
  23. public void wheel(){
  24. System.out.println("鼠标滚动");
  25. this.trigger(MouseEventType.ON_WHEEL);
  26. }
  27. public void move(){
  28. System.out.println("鼠标移动");
  29. this.trigger(MouseEventType.ON_MOVE);
  30. }
  31. public void over(){
  32. System.out.println("鼠标悬停");
  33. this.trigger(MouseEventType.ON_OVER);
  34. }
  35. }

MouseEventType:枚举,里面存储mouse各种操作定义:

  1. package Observer.mouse;
  2. public enum MouseEventType {
  3. ON_CLICK,
  4. ON_DOUBLE_CLICK,
  5. ON_UP,
  6. ON_DOWN,
  7. ON_WHEEL,
  8. ON_MOVE,
  9. ON_OVER;
  10. }

MouseEventCallback:观察者,回调响应的逻辑。

  1. package Observer.mouse;
  2. import Observer.core.Event;
  3. /**
  4. * 回调响应的逻辑
  5. * 观察者
  6. */
  7. public class MouseEventCallBack {
  8. public void onClick(Event e){
  9. System.out.println("这是鼠标单击以后要执行的逻辑");
  10. System.out.println("=======触发鼠标单击事件========\n" + e);
  11. }
  12. public void onDoubleClick(Event e){
  13. System.out.println("=======触发鼠标双击事件========\n" + e);
  14. }
  15. public void onUp(Event e){
  16. System.out.println("=======触发鼠标弹起事件========\n" + e);
  17. }
  18. public void onDown(Event e){
  19. System.out.println("=======触发鼠标按下事件========\n" + e);
  20. }
  21. public void onMove(Event e){
  22. System.out.println("=======触发鼠标移动事件========\n" + e);
  23. }
  24. public void onWheel(Event e){
  25. System.out.println("=======触发鼠标滚动事件========\n" + e);
  26. }
  27. public void onOver(Event e){
  28. System.out.println("=======触发鼠标悬停事件========\n" + e);
  29. }
  30. }

测试类:

  1. package Observer.mouse;
  2. import Observer.core.Event;
  3. import java.lang.reflect.Method;
  4. public class MouseTest {
  5. public static void main(String[] args) {
  6. try {
  7. Mouse mouse = new Mouse();
  8. MouseEventCallBack mouseEventCallBack = new MouseEventCallBack();
  9. //方法定义
  10. Method onClick = MouseEventCallBack.class.getMethod("onClick", Event.class);
  11. Method onDoubleClick = MouseEventCallBack.class.getMethod("onDoubleClick", Event.class);
  12. Method onUp = MouseEventCallBack.class.getMethod("onUp", Event.class);
  13. Method onDown = MouseEventCallBack.class.getMethod("onDown", Event.class);
  14. Method onWheel = MouseEventCallBack.class.getMethod("onWheel", Event.class);
  15. Method onOver = MouseEventCallBack.class.getMethod("onOver", Event.class);
  16. Method onMove = MouseEventCallBack.class.getMethod("onMove", Event.class);
  17. //加入监听
  18. mouse.addListener(MouseEventType.ON_CLICK,mouseEventCallBack,onClick);
  19. mouse.addListener(MouseEventType.ON_DOUBLE_CLICK,mouseEventCallBack,onDoubleClick);
  20. mouse.addListener(MouseEventType.ON_UP,mouseEventCallBack,onUp);
  21. mouse.addListener(MouseEventType.ON_DOWN,mouseEventCallBack,onDown);
  22. mouse.addListener(MouseEventType.ON_WHEEL,mouseEventCallBack,onWheel);
  23. mouse.addListener(MouseEventType.ON_OVER,mouseEventCallBack,onOver);
  24. mouse.addListener(MouseEventType.ON_MOVE,mouseEventCallBack,onMove);
  25. //被观察者执行相对应的动作
  26. mouse.click();
  27. mouse.doubleClick();
  28. mouse.up();
  29. mouse.down();
  30. mouse.wheel();
  31. mouse.over();
  32. mouse.move();
  33. }catch (Exception e){
  34. e.printStackTrace();
  35. }
  36. }
  37. }

执行测试类输出结果:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhcnJ5cHR0ZXI_size_16_color_FFFFFF_t_70 1

可以看到,当对应的方法加入监听中之后,被观察者执行了什么操作,观察者也就有了对应的处理。

发表评论

表情:
评论列表 (有 0 条评论,269人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java 设计模式观察模式

    一、了解观察者模式 1.1 什么是观察者模式 观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。 典型的问

    相关 JAVA设计模式观察模式

    1、初步认识 观察者模式的定义:   在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。 大白话:   其实就是