特别谈到DI功能我不是Angular的粉丝,而且我对Angular使你的代码更容易测试的想法并不是真的太相信,或者甚至让它更容易编写更可测试的代码。
在我看来,你最终得到了许多额外的抽象层,实际上是间接的,只是为了支持一些魔法" - 即,自动实例化函数参数名称。没有那个功能 - 就是:神奇地获得一个$ http或$ car的实例,或者当你的函数被调用时的任何东西 - 它似乎并没有提供那么多。
在使这些调用显式化的过程中,它有多少额外的努力,以及减少多少间接和魔法?你最终得到的是一个全球性的" (从你的应用程序的角度来看)命名空间......所以手动操作真的只有一些方便。
来自文档:
myModule.factory('greeter', function($window) {
return {
greet: function(text) {
$window.alert(text);
}
};
});
function MyController($scope, greeter) {
$scope.sayHello = function() {
greeter.greet('Hello World');
};
}
这里的魔力是" greeter" 根据参数的名称自动注入,对吗?我假设它对于$ scope来说是相同的,虽然据我所知,所有控制器都应该将$ scope作为第一个参数,所以可能不是这样。
一个非神奇的例子:
function MyController() {
var scope = myApp.get('scope');
var greeter = myApp.get('greeter');
scope.sayHello = function() {
greeter.greet('Hello World');
}
}
正如您所看到的,我只是添加了一个" .get()"获取依赖项的方法。我理解Angular完全可以实现这一点 - 但这不是我所读过的文档所提出的主要案例。
非魔法测试:
function myControllerTest() {
var scope = {};
var greeter = { greet: function() {} };
myApp.set('scope', scope);
myApp.set('greeter', greeter);
// ... run an actual test on MyController here
}
我并没有真正对Angular做过任何重大的事情,但随着我变得越来越老,越来越谦虚,我发现我越来越不喜欢魔法了。我非常高兴添加(比如说)多20%的行代码,以避免间接级别,这意味着无论框架或语言如何,我都无法轻松浏览代码。
有人可以给出一个合理的例子,说明角度对DI的影响与某些基本约定相比没有相对无问题吗?我错过了什么好处"魔法"只是为了避免明确定义依赖关系?
答案 0 :(得分:3)
依赖注入是在经典OOP文献中说出所谓“隔离”的一种奇特而新的方式。这意味着对象不应该了解外部世界。它是封装的补充原则,它说外部世界不应该知道对象的内部运作。实际上,这意味着如果使用依赖注入,则不使用全局变量。依赖注入不是一个框架,它是一个设计原则。 Angulars DI框架只是为了让它更容易。正如您所指出的那样,使用DI经常会引入间接性。这是你支付的价格。如果你不同意,那就完全没问题了。 DI肯定会让你的代码更难理解很多情况。然而,它产生了更多可组合和模块化的软件。
在你的'非魔法'版本中,你基本上引入了'服务定位器'。这导致对myApp
的依赖。从DI的角度来看,这种依赖性是最糟糕的,因为它是隐藏的,间接的和全球的。 '隐藏'意味着它不是函数参数。只有在阅读代码本身时才会看到它。间接意味着,你真正关心的是greeter
,但你所依赖的是myApp
。全球应该很明显。有很多争论为什么全局变量一般都很糟糕,但是对于测试,问题是你的测试彼此共享状态。您不能以这种方式单独运行测试。这可能导致“测试片状”,这意味着某些测试有时会失败,有时则不会,这取决于另一个测试。
答案 1 :(得分:0)
首先,我完全理解你的观点。
今天我发现自己在使用任何js框架方面都非常有选择性。他们似乎无处不在,其中很多人,你的20%以上真的会更好,并避免那些额外的层。
由于我对这一切都比较新,所以我不想在这里与你争辩......让我也对Angular发表意见。
支持像javascript这样的技术对新手来说非常具有挑战性,而且我觉得很容易从错误的脚开始,而没有人在路上瞎了一下。 特别是如果您的目标是在应用程序中达到某种程度的复杂性。
我们都知道好的模式提供了一个坚实的基础,而且正是在我第一次看到它时,Angular吸引了我的注意力。
一切都在那里。简单,纤薄,快速,易于入手和理解。背后的概念和模式是众所周知的,并且对我来说很有意义(DI,MVC,TDD,模块化,关注点的良好分离,强大的绑定策略),尽管我还不知道如何使用javascript实现它们那个时候。
所以基本上它让我开始,让我开始很好。今天我比以前知道的更多,我看到很多其他框架说再见,原因与你指出的相同。但是Angular留了下来,最初的架构对我来说太棒了!
也许如果我有时间,我会选择一个自己的角度,只是为了它的一脚......但是当我想到它时,我想我不会让它变得太多不同。 那为什么要这么麻烦?
此外,社区发展迅速,文档非常好,每个角落都有帮助!
我知道你在这里谈论DI和可测试性,但这只是你从Angular获得的一小部分。仅出于此目的,我确信您可以很好地完成替代方案:)
顺便说一下,谈论可测试性时,请看一下角度情节跑步者,我知道它已经停止了(Lord知道为什么?!?)但是......
这是一种魔力!