你想必聽過依賴注入(DI)模式吧?
無論是後端火的一塌糊塗的Spring框架,還是前端潮流angular.js,處處可見依賴注入的身影。
它這個名詞有些晦澀,但核心的思想卻很簡單。
用一句俗話說就是,「要風得風,要雨得雨」,或者說是「飯來張口,衣來伸手」。
你聽了我這麼一解釋,大概還有些迷糊,我就先上一個例子。
下面是一些模組,他們也被稱為「依賴」,被儲存在一個hash物件中:
var deps = { 'firstDependency': function () {return 'this is firstDependency';}, 'secondDepency': function () {return 'this is secondDepency';}, };
下面則是一個依賴注入的管理器,到時候是要new出來的:
var DI = function (dependency) { this.dependency = dependency; };
在new的時候,就把deps當參數傳進去了。
好,現在問題的關鍵來了,我們要寫的東西:
DI.prototype.inject = function (func) {......};
這個inject注入方法綁定在DI的原型上,接收一個函數作為參數。
那它該怎麼使用呢?
var di = new DI(deps); var myDependentFunc = di.inject(function (secondDepency, firstDependency) { firstDependency(); secondDepency(); }); myDependentFunc();
大家先觀察一下這個inject傳入的匿名函數,它代表需求,是我們需要注入的地方。
先看看它的形參,
secondDepency, firstDependency
這裡有兩個參數,即代表兩個需求,到時候,我們要分析這兩個參數,找出相關模組。
好,回到inject函數的編寫問題上來,第一步該怎麼做?
先取得inject傳進來函數的toString()形式:
//第一步 DI.prototype.inject = function (func) { func.toString(); };
接著,分析這個字串,找出所有的形參使用正規或字串分割截取都可以,這裡我用的後者。
//第二步 DI.prototype.inject = function (func) { var args = findArgs(func.toString()); };
找出所有的形參後,第三步,從模組hash表中,找出對應的模組函數,存放進實參列表中。
realArgs
實參列表
:String.prototype.trim=function(){
return this.replace(/(^\s*)|(\s*$)/g, "");
};
var findArgs = function(funcStr){
var bracket1 = funcStr.indexOf("(");
var bracket2 = funcStr.indexOf(")");
var argsStr = funcStr.slice(bracket1+1,bracket2);
var args = argsStr.split(",");
return args.map(function(e){
return e.trim();
});
};
注入
,inject返回一個閉函數,並使用匿名函數,透過函數來執行的真實包實進行。 ,注入
。
//第三步
DI.prototype.inject = function (func) {
var args = findArgs(func.toString());
var realArgs = [];
for(var i=0;i<args.length;i++){
var dep = this.dependency[args[i]];
if(dep){
realArgs.push(dep);
}
}
//......
};