ejabberd源码学习——方法注册模式

什么叫方法注册模式?

      简言之,就是在方法被调用之前,先将方法名与调用此方法的触发条件的关键字建立一种映射关系,当指定的触发条件成立时,相应的方法则将会被调用。称之为方法注册模式,实乃一家之言,关键囿于人懒,从而书读得少,代码写得寡。闲话休谈,待入正题。

     在学习ejabberd源码(版本14.07)中,发现通过配置表就可以使得某些模块启用或不启用,相当灵活,其主要是通过利用第一段所说的方法注册模式来实现。可以发现很多mod_xxx模块的start方法中都有下面两个方法的调用:

      gen_iq_handler:add_iq_handler(Component, Host, NS, Module, Function,Type);

      ejabberd_hooks:add(Hook, Host, Module, Function, Seq);

 

而其stop方法中则都有

     gen_iq_handler:remove_iq_handler(Component, Host, NS);

     ejabberd_hooks:delete(Hook, Host, Module, Function, Seq);

 

前后start与stop方法中的以上方法调用是一一对应的。其功能就相当于是注册与注销。深入查看里层的代码,会发现gen_iq_handler:add_iq_handler/6 与 ejabberd_hooks:add/5方法是将方法名与方法的触发条件写入ets中,从而建立一种映射关系, gen_iq_handler:remove_iq_handler/3与ejabberd_hooks:delete/5则是将之前建立的映射关系删除。

 

     在建立了方法名与方法的触发条件关键字的映射关系后,在后续过程,就可以通过触发条件关键字来查找到相对于的模块方法名,进而相应的模块方法得于执行。比如ejabberd_sm模块中维护了iq包的处理方法映射关系,ejabberd_hooks模块中则维护了各种各样的hooks,在收到不同的iq包时,通过xmlns值或原子值,在ets中查找到相应的处理方法。在很多不同的业务处理时,通过此种方式可以避免条件语句判断过长,模块划分更方法,更有利于人员分工编写,同时有很大的灵活性(可以启用某些模块,也可不启用)。

 

   上述方式得益于erlang是一种动态语言,模块、方法名可以赋于一个变量,通过变量来执行。其实在面向对象语言中,这恰恰就是多态特性的拿手好戏,通过父类/接口类来声明一致的接口方法, 建立父类指针/引用与关键字的映射关系,进而达到以上类似的效果。

 

posted @ 2015-08-13 21:34  walkon  阅读(429)  评论(0编辑  收藏  举报