对于依赖注入的思考
note 突然想明白了为什么要有依赖注入了:这里只讨论在组合优于继承的这种情况下
一定会有许多的函数组合情况,而且还会有函数组合的组合,这样实质上形成了一个函数之间的依赖链路。
如果是直接在代码中硬编码对应的函数组合的话,我要实现一个新的高阶组合他和原来的高阶组合的唯一区别只是一个基础函数的实现不一致,那我基本需要重新复制一遍原来的组合代码,然后修改其中一个调用
如果要想复用原来的高阶组合,而只是修改其中对于该基础函数的替换的话,要么将该函数作为参数传递(这个传递链路可能很长),而依赖注入就是为了解决这个问题而存在的。
有了依赖注入,只需要在编写代码的时候就通过依赖注入来调用函数,后续的替换就十分的方便了。
js
function baseFn_A(){}
function baseFn_B(){}
function higherFn_B(){
baseFn_A()
//other baseFn ...
}
function higherFn_C(){
higherFn_B()
//other baseFn / higherFn ...
}
// 这中间还可能有更多层次的这样的套娃
// 上面存在一个依赖链路 higherFn_C>higherFn_B>baseFn_A
// 如果我要实现一个新的函数 higherFn_C2 ,它和 higherFn_C 唯一的区别就是调用的是 baseFn_B 而非 baseFn_A
// 我认为依赖注入就是为了更方便的创建 higherFn_C2 而不需要改动特别多的代码
如何实现依赖注入
依赖注入可以使用链表来理解。js 的原型链就可以认为是一种依赖注入
只要实现 inject 和 provide 这两个函数就可以了
provide 实现 :接受一个 key 和 value , 将这两个参数和当前节点相绑定
inject 实现 :接受一个 key, 在任意一个节点,沿父级一直向上通过 key 查询对应的注入的值,找到了就返回,没有就找父级的父级。
inject 的实现基本和 js 对象基于原型链查找属性值的实现方式是一样的。所以我说 js 的原型链就可以认为是一种依赖注入
比如 vue 中的依赖注入系统,这里的链表是组件树中,将组件理解为节点,然后一直查找上一层组件,一直到顶层,其中经过的所有节点就是一个链表,基于这个链表,最末端的节点,可以获取他的任意一个父级节点 provide 的值,并且在 key 相同的情况下 inject 的是离他最近的一个节点 provide 的值
但如果我们要以函数为节点,以函数调用栈作为链表来实现一个依赖注入系统可行吗?
答案是可以但又不可以,因为在浏览器中是受限的,只能基于
zone.js 来实现(存在缺陷)