美文网首页
事件驱动模型

事件驱动模型

作者: 枫叶_huazhe | 来源:发表于2018-02-07 12:10 被阅读0次

    观察者模式与事件驱动模型

    观察者模式:

    发布 - 订阅 , 变化 - 更新
    
    

    事件驱动模型

    请求 - 响应, 事件发生 - 事件 处理
    

    2.事件驱动模型

    事件源
    • 持有监听器列表,或者各种类型监听器
      • 可以只需要持有监听器的引用,在具体调用时,通过set将监听器实例set进去.
      • 这样做的目的时,不需要让事件源去提供注册和注销的api,直接通过set即可。
      //例子,以button为事件源
      public class Button {
          private ClickListener clickListener;
          private DbClickListener dbClickListener;
          // setter getter 省略
      }
      //具体使用时
      public class ButtonJsp {
          //持有事件源
          private Button button;
          
          public ButtonJsp() {
              button = new Button();
              button.setClickListener(new ClickListener(){
                  public void click(ClickEvent event) {
                      System.out.println("do something")
                  }
              });
          }
      }
      
    • 提供注册与注销api 给监听器注册(非必须,变种)
    • 触发事件,fireEvent
    事件对象(AppEvent)
    • 可以定义各类事件
    • 必须持有事件源
    • 可以附带附加信息
    监听器
    • 持有某个事件,监听事件
    • 定义行为,事件触发后会回调此行为
    • 向事件源注册和注销自己
    Manager类
    • 保存事件源列表,在事件源的构造器中注册自己

      • 如果有多的事件源对象,此管理器可以很好的做到管理
      • 例如事件源是作者,而这里可以维护多个作者
      • 或者例如下文中dapeng框架里的多个Application
      public class Writer {
          private String name;
          private String novel;
          
          public Writer(String name) {
              this.name =this.name;
              Manager.getInstance().add(this);
          }
      }
      
    • 维护事件源的信息,拿到具体的事件源后,给监听器注册自己。

      • 例子,监听器读者监听作者Writer
        public void register(String writerName) {
            Manager.getInstance().getWriter(writeName).register(this);
        }
        

    3.以dapeng-container为例

    • 3.1 监听器AppListener
    public interface AppListener extends EventListener {
    
        public void appRegistered(AppEvent event);
    
        public void appUnRegistered(AppEvent event);
    }
    

    持有AppEvent事件,定义注册和注销自己

    • 3.2 事件AppEvent
    public class AppEvent extends EventObject {
    
        private AppEventType eventType;
    
        public AppEvent(Application application, AppEventType eventType) {
            super(application);
            this.eventType = eventType;
        }
    
        public AppEventType getEventType() {
            return this.eventType;
        }
    }
    

    事件对象,需要持有事件源,可选持有附加信息。

    这里在构造器里,除了持有数据源Application外,还增加AppEvent附加信息,作更进一步判断.

    • 3.3 事件源Application

    一般情况下是事件源来持有监听器列表和注册注销api的,dapeng在这里做了一个代理,注册和注销api放到来DapengContainer中。

    并且,除了持有监听器列表之外,还持有事件源列表。如下:

    private List<AppListener> appListeners = new Vector<>();
    
    private List<Application> applications = new Vector<>();
    
    提供监听器的注册和注销api
    public void registerAppListener(AppListener listener) {
            this.appListeners.add(listener);
    }
    
    public void unregisterAppListener(AppListener listener) {
            this.appListeners.remove(listener);
    }
    
    具体某个监听器注册自己的逻辑
    public ZookeeperRegistryPlugin(Container container) {
            this.container = container;
            container.registerAppListener(this);
    }
    

    监听器持有了container的引用。在构造函数里传入,并注册自己。

    Why?

    • dapeng里面有很多application(每一个app目录下的app.jar就是一个应用服务。如app下的订单服务和会员服务,他们是分离开的。)
    • 之后,容器在注册了具体的application后,在application列表中加入当前的app
    • 接下来,遍历application列表,然后调用监听器自己的触发事件。
    public void registerApplication(Application app) {
            this.applications.add(app);
            this.appListeners.forEach(i -> {
                try {
                    i.appRegistered(new AppEvent(app, AppEventType.REGISTER));
                } catch (Exception e) {
                    LOGGER.error(" Faild to handler appEvent. listener: {}, eventType: {}", i, AppEventType.REGISTER, e.getStackTrace());
                }
            });
    }
    

    这样,dapeng的事件驱动模型我们就分析完了。

    总结

    • dapeng里的Contaimer就相当于是一个Manger管理类,维护着事件源列表和监听器列表。
    • 它提供监听器和事件源来注册自己
    • 它作为一个代理,每当注册了一个app后,他会触发事件,然后遍历监听器列表,来发布事件

    相关文章

      网友评论

          本文标题:事件驱动模型

          本文链接:https://www.haomeiwen.com/subject/gxvozxtx.html