AngularJS依赖注入的好处是什么?

8

我已经使用Angular一段时间了,但是我不认为它比之前的编码方式有所改进。

首先,我不明白将项目放在一个中心对象中存在什么问题。毕竟,注入器是一个单例,将您的依赖项查找到一个中心位置,因此Angular确实有一个中心对象,只不过它被隐藏起来了。如果正确使用命名空间,则命名空间并不一定意味着耦合。即使完成时,您也不需要使代码中的每个对象与其他对象松散耦合。此外,每次创建独立的JS脚本时,您都必须将其包装到Angular中,以使它们协同工作。

第二,每次声明所有依赖关系非常冗长(特别是在缩小时),因此从可读性的角度来看,与适当的命名空间相比没有任何收益。

第三,性能提升微不足道。它强制我在各处使用单例模式,但如果需要,我可以自己做到这一点,而且大多数情况下,我不需要(网络和DOM操作是我的瓶颈,而不是JS对象)。

最后,在增强版的HTML和自动双向绑定方面,我很喜欢它,但我不明白注入机制如何比其他框架处理依赖关系更好,特别是它甚至没有像require.js那样提供动态加载。在编码时,我还没有看到任何使用案例,让我想到“哦,这就是它比以前好多了,我懂了”的情况。

您能向我解释一下这种技术选择为项目带来的好处吗?

目前我只能看到一个好处:规范和最佳实践的执行。对于创建库生态系统来说,这是一个重要因素,但目前我在Angular社区中还没有看到它的成果。


单元测试是在Angular中使用DI的主要优势之一。 - Ajay Beniwal
如果您只写注释而不编写响应,我无法投票。此外,我需要更多关于 DI 如何使单元测试更好的信息。如果您使用具有 getter 和 setter 的解耦组件编写代码,并且具有一个中央命名空间,则不会对单元测试造成问题。那么它带来了我错过的什么? - Bite code
依赖注入展示了一个类在执行其所承担的职责时需要什么。通过构造函数明确定义它所需的内容,而不是隐藏实际要求以使类能够工作,这使得代码更易读,进而更易于维护。这就是为什么它使得测试变得更加容易,因为你可以直接通过应用程序代码库的接口(构造函数)公开它们的位置。这是我的理解。 - Patrick Magee
你可以把它写成一个答案,因为我会点赞的。 - Bite code
1个回答

7
对我来说,Angular的依赖注入在改进我的项目中有几个方面,我将在此列出。我希望这能向你展示其他人如何受益于它,但如果你是一个组织良好、经验丰富的JS开发者,那么可能不是同样的情况。我认为,在某些时候,这只是开发自己的工具和编码指南的问题。
统一、声明式依赖解析
JS是动态语言(这是新鲜事,对吧?),它给程序员带来了很多权力,甚至更多的责任。组件可以通过传递各种对象相互交互:常规对象、单例、函数等等。他们甚至可以使用未被其他组件使用的代码块。
JS从来没有(也很可能永远不会)像其他语言(Java、C、C#)一样有一个统一的方式声明公共、私有或包(模块)作用域。当然,有封装逻辑的方法,但问任何新手如何使用它,他们可能根本不知道该怎么做。
我喜欢DI(不仅仅是在Angular中,而是在一般情况下),因为你可以列出组件的依赖项,而不必担心这个依赖项是如何构造的。这对我来说非常重要,特别是在Angular中的DI允许你解决两种类型的组件:从框架本身(如$http)或自定义组件(如我最喜欢的eventBus,我用它来包装$on事件处理程序)。
很多时候,我看一下服务的声明,就知道它做了什么以及依赖项是什么!
如果我要在组件深处构造和/或使用所有这些对象,那么我总是必须彻底分析实现并从各个方面检查它。如果我在依赖项列表中看到localStorage,我知道我正在使用HTML5本地存储来保存一些数据。我不必在代码中寻找它。
组件的生命周期
我们不再需要担心某些组件的初始化顺序。如果A依赖于B,那么DI将确保当A需要它时,B已经准备好了。
单元测试
使用DI时,模拟组件会有很大帮助。例如,如果您有控制器:function Ctrl($scope, a, b, c, d),那么您立即就知道它依赖于什么。您注入适当的模拟,并确保与您的控制器交谈和监听的所有方都被隔离开来。如果您在编写测试时遇到问题,那么您很可能搞乱了抽象级别或违反了设计原则(直径定律、封装等)。
良好的习惯
是的,你可以使用命名空间来正确管理对象的生命周期。在需要时定义单例,并确保没有人弄乱你的私有成员。
但是,如果框架可以为您完成此操作,您是否需要它呢?
直到我学会Angular之前,我才开始“正确地”使用JS。并不是因为我不在意,而是因为我只是将JS用于一些基于jQuery的UI微调。
现在情况不同了,我有了一个不错的框架,它迫使我遵循良好的实践,但同时也赋予了我使用JS最佳特性扩展它的巨大力量。
当然,糟糕的程序员仍然可能破坏最好的工具,但从我最近阅读D·克罗克福德的《JS优秀部分》中学到的内容表明,人们曾经对其进行了非常可怕的操作。幸运的是,由于像jQuery、Angular和其他工具的出现,我们现在有了一些很好的工具,可以帮助我们编写好的JS应用程序,并在这样做时坚持最佳实践。
结论:
正如你所指出的,通过做这三件事,你可以编写出优秀的JS应用程序:
1. 命名空间-这可以避免向全局命名空间添加内容,避免潜在的冲突,并允许在需要时轻松解析正确的组件。 2. 创建可重用的组件/模块- 例如,使用函数模块模式并明确声明私有和公共成员。 3. 管理组件之间的依赖关系-通过定义单例,允许从某个“注册表”检索依赖项,当不满足某些条件时,禁止执行某些操作。
Angular通过以下方式实现:
1. 具有“$injector”的管理组件之间的依赖关系,并在需要时检索它们。 2. 强制使用具有私有和公共API的工厂函数。 3. 使组件直接交流(通过相互依赖)或通过共享的$scope链交流。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接