JavaScript 中的依赖倒置原理
题
有谁可以帮忙说明一下 依赖倒置原则 在 JavaScript 中 jQuery?
这将强调并解释这两点:
A。高层模块不应该依赖于低层模块。两者都应该依赖于抽象。
B.抽象不应该依赖于细节。细节应该取决于抽象。
什么是抽象或高/低级模块?
这对我的理解确实有帮助,谢谢!
解决方案
我要说的浸适用于JavaScript多相同的方式,因为它适用于大多数编程语言,但是你必须意识到的作用鸭打字。让我们做一个例子看什么我的意思是...
让我说我想要联系的服务器对某些数据。不应用浸,这可能看起来像:
$.get("/address/to/data", function (data) {
$("#thingy1").text(data.property1);
$("#thingy2").text(data.property2);
});
与浸,我可能会写这样的代码
fillFromServer("/address/to/data", thingyView);
那里的抽象 fillFromServer
可以 对于特定的情况下,我们想到使用google i/o大会的阿贾克斯 应实施为
function fillFromServer(url, view) {
$.get(url, function (data) {
view.setValues(data);
});
}
和抽象 view
可以实现 对于特定的情况下查看基于元件的Id thingy1
和 thingy2
作为
var thingyView = {
setValues: function (data) {
$("#thingy1").text(data.property1);
$("#thingy2").text(data.property2);
}
};
原则一:
fillFromServer
属于低级别的模块处理,因为它不会低水平之间的相互作用服务器和视图。什么比如说,settingsUpdater
对象将是一个更高级别的模块,这将依靠fillFromServer
抽象---不是在细节上,它是在这种情况下实施通过的!- 同样地,
fillFromServer
并不取决于具体情况DOM元素及其标识来执行其工作;相反,它取决于抽象的view
, ,这对于它的目的是任何类型有一个setValues
法。(这是什么是"鸭打字。")
原则B:
这是有点不太容易看到在JavaScript,其鸭子-打字;特别是,类似的东西 view
不得(即取决于)一些类型的 viewInterface
类型。但是,我们可以说,我们的具体实例, thingyView
, 是一个 详细 那"取决于"上抽象 view
.
实际上,它是"根据"事实上,呼叫人了解什么样的方法应该称,即呼叫者是 意识到 适当的抽象概念。在通常的面向对象的语言,很容易看到的依赖 thingyView
明确的抽象本身。在这样的语言,抽象将体现在一个接口(说 IView
C#或 Viewable
Java),并明确依赖的是通过继承(class ThingyView : IView
或 class ThingyView implements Viewable
).同样的情绪适用,但是。
为什么这个很酷吧?好吧,让我们说有一天我需要把服务器的数据成本框Id text1
和 text2
而不是的 <span />
s Id thingy1
和 thingy2
.此外,我们来说,这种代码已被称为非常非常频繁,和制定基准显示,重要的绩效,正在失去了通过使用!然后我可以只是创建一个新的"执行"的 view
抽象,像这样:
var textViewNoJQuery = {
setValues: function (data) {
document.getElementById("text1").value = data.property1;
document.getElementById("text2").value = data.property2;
}
};
然后我注入这个特别的实例景抽象成我的 fillFromServer
抽象:
fillFromServer("/address/to/data", textViewNoJQuery);
这需要 没有 更改 fillFromServer
代码,因为它只取决于抽象的 view
与 setValues
方法,而不是在细节DOM以及我们如何进行访问。这不仅是令人满意,我们可以重复使用的代码,它还表明,我们已经干净的分离我们的关切和创建非常未来的代码。
其他提示
编辑:
这显示了 DIP 在原始 JavaScript 中的用法以及 不太完整的 jQuery 示例。然而,下面的描述可以很容易地应用于 jQuery。请参阅底部的 jQuery 示例。
最好的方法是利用“适配器模式”——也称为“包装器”。
适配器基本上是一种包装对象或模块的方法,使其提供相同的功能 一致的界面 对其 家属. 。这样,依赖类(通常是 更高层次 class) 可以轻松地交换相同类型的模块。
这方面的一个例子是高级(或 上文) 依赖于 Geo/Mapping 模块的模块。
我们来分析一下这个。如果我们的上述模块已经在使用 GoogleMaps,但管理层决定使用 LeafletMaps 更便宜——我们不想重写每个方法调用 gMap.showMap(user, latLong)
到 leaflet.render(apiSecret,latLong, user)
, ,等人。如果必须以这种方式将我们的应用程序从一个框架移植到另一个框架,这将是一场噩梦。
我们想要什么:我们想要一个提供相同功能的“包装器” 一致的界面 到上面的模块——并对每个 下层模块 (或者 基础设施 模块)。
这是一个简单的例子:
var infra1 = (function(){
function alertMessage(message){
alert(message);
}
return {
notify: alertMessage
};
})();
var infra2 = (function(){
function logMessage(message){
console.log(message);
}
return {
notify: logMessage
};
})();
var Supra = function(writer){
var notifier = writer;
function writeMessage(msg){
notifier.notify(msg);
}
this.writeNotification = writeMessage;
};
var supra;
supra = new Supra(infra1);
supra.writeNotification('This is a message');
supra = new Supra(infra2);
supra.writeNotification('This is a message');
请注意,无论我们使用哪种类型的低级模块“写入”(在本例中 infra1
和 infra2
),我们不必重写高级模块的任何实现, Supra
. 。这是因为 DIP 利用了两种不同的软件设计原则:“IoC”(控制反转)和“DI”(依赖注入)。
我遇到过的最好的类比是下图。
每个电源都依赖于 界面 特定于需要插入其中的事物类型。
jQuery 说明:
这种模式可以很容易地应用于 jQuery 等框架的使用。一个例子是简单的 DOM-Query 句柄。我们可以使用 DIP 来允许松散耦合,这样如果我们决定切换框架或依赖本机 DOM 查询方法,维护就很容易:
var jQ = (function($){
return {
getElement: $
};
})(jQuery);
var nativeModule = (function(){
return {
getElement: document.querySelector
};
})();
var SupraDOMQuery = function(api){
var helper = api, thus = this;
function queryDOM(selector){
el = helper.getElement(selector);
return thus;
}
this.get = queryDOM;
};
var DOM;
DOM = new SupraDOMQuery(jQ);
DOM.get('#id.class');
DOM = new SupraDOMQuery(nativeModule);
DOM.get('#id.class');
显然,这个例子需要更多的功能才能实用,但我希望它能表达要点。
基本上,适配器和外观之间的差异变得有些微不足道。在 Facade 中,您可能看到的是包装 API 或另一个模块的单个模块;而适配器为其每个模块创建一致的 Facade API,并利用此技术来避免紧密耦合。
大多数 JavaScript 设计模式书籍都会讨论适配器模式;专门讨论“jQuery 适配器”的一个是 学习 JavaScript 设计模式 经过 阿迪·奥斯马尼 由...出版 奥莱利 -- 这里. 。不过,我也建议研究一下 专业 JavaScript 设计模式 经过 达斯汀·迪亚兹和罗斯·哈姆斯 由...出版 阿普雷斯 -- 一探究竟. 。尽管如此,我认为了解我们计划实现与 jQuery 相关的 DIP 的背景很重要。
我希望这有助于澄清事情:)
找到一些有用的插图此处。
在JavaScript的jQuery依赖倒置原理
有没有DI和jQuery之间的任何连接。 DI是所有关于从精铸件结构和装配应用。 jQuery是围绕DOM,没有一个方便的包装更,它没有任何结构或组件。
您可以使用DI组装你的JavaScript应用程序,但它会看起来更相同的,无论你使用jQuery的或没有。