模块的静态与动态循环依赖

场景:

 

循环依赖 我是不支持的,但现实中似乎又确实需要循环依赖,例如前端的选择器场景 (ie<8):

 

首先实现了 DOM 模块来保证各个浏览器的兼容性以及 api 的易用性,其中包含必要简单的选择器逻辑

 

然后实现了高级选择器模块,但这并不是最常用,为了效率该模块是不放入核心 DOM 模块中的,而选择将它作为独立模块 :selector,显然 selector 模块依赖于 DOM 进行 dom 遍历.

 

S.add("selector",function(){

},{requires:["dom"]});

 

而 DOM 中会进行判断是否当前选择器字符串过于负责而自己不能处理,需要高级选择器模块介入:

 

S.add("dom",function(S,Selector){
  return {
      querySelectorAll:function(q){
           if(isAdvanced(q)){
               return Selector.querySelectorAll(q);
           } else{
               // simple logic
           }
      }
  };
},{requires:["selector"]});

 

这时就形成了循环依赖

 

解决:

 

其实我们需要区分模块间到底是静态依赖还是动态依赖,静态依赖指模块的初始化就需要另一个模块参与,而动态依赖则是指直到模块的运行期才会需要调用另一个模块,对于静态循环依赖这个问题我觉得是无解的,而对于动态循环依赖则是完全可以绕过.

 

动态循环依赖可以参考类似 serviceloader 的做法,DOM 模块完全可以动态取得高级选择器接口的一个具体实现模块,而selector 模块实现接口并保证自己可以被找到即可:

 

DOM 模块:

 

S.add("dom",function(S){
  return {
      querySelectorAll:function(q){
           if(isAdvanced(q)){
               return S.ServiceLoader.load("selector").querySelectorAll(q);
           } else{
               // simple logic
           }
      }
  };
});

 

高级选择器模块仍可以依赖 DOM ,实现 querySelectorAll 接口(概念上,动态语言完全没必要),并注册自己即可.

 

而 ServiceLoad.load 完全可以和模块系统结合在一起,用户可以通过模块系统静态或动态载入一些高级附加模块,ServiceLoad.load 询问模块系统即可得到实现了高级选择器接口的具体模块.

 

 

 

refer:

 

static vs dynamic 1 ,2

 

circular dependency wiki

 

java.util.ServiceLoader api

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值