angularjs - AngularJS 依赖注入(inject)有什么好处?

标签 angularjs dependency-injection

我已经使用 Angular 一段时间了,但我看不出它比我以前的编码方式有什么改进。
首先,我看不出有一个中心对象来保存您的项目有什么问题。毕竟,注入(inject)器是一个单例,它将您的依赖项查找到一个中心位置,所以 Angular 确实有一个中心对象,它只是隐藏的。如果使用得当,命名空间并不一定意味着耦合。即使完成了,您也不需要代码的每个对象都与其他对象松散耦合。此外,无论何时您创建一个独立的 JS 脚本,您都必须将其包装到 Angular 中,以使它们能够很好地协同工作。
其次,每次都声明所有依赖项非常冗长(尤其是在缩小时),因此与正确的命名空间相比,从可读性的 Angular 来看没有任何好处。
第三,性能增益很小。它迫使我在任何地方都使用单例,但如果需要,我可以自己做,而且大多数时候,我不需要(网络和 DOM 操作是我的瓶颈,而不是 JS 对象)。
最后,我喜欢“增强的”HTML 和自动双向绑定(bind),但我看不出注入(inject)如何使它比其他框架处理依赖项的方式更好,因为它甚至不提供动态像 require.js 一样加载。我没有看到任何用例,我在编码时对自己说“哦,这是比以前好多了,我明白了”。
你能向我解释一下这个技术选择给项目带来了什么好处吗?
我现在只能看到一个:约定和最佳实践执行。创建一个 lib 生态系统是一件大事,但目前我在 Angular 社区中看不到它的成果。

最佳答案

给我 Angular 的依赖注入(inject)如何改进我的项目有几个方面,我将在这里列出。我希望这将向您展示 OTHERS 如何从中受益,但是如果您组织良好且经验丰富的 JS 开发人员,那么对于您来说可能情况并非如此。我认为在某些时候,这只是开发自己的工具和编码指南的问题。

统一的声明式依赖解析

JS 是动态语言(那是新的,嗯?),它赋予程序员很大的权力,甚至更多的责任。组件可以通过传递各种对象以各种方式相互交互:常规对象、单例、函数等。它们甚至可以使用其他组件甚至没有提到要使用的代码块。

JS 从来没有(而且很可能永远不会)像其他语言(Java、C、C#)那样有一种统一的方式来声明公共(public)、私有(private)或包(模块)范围。当然有封装逻辑的方法,但是问任何语言的新手,他根本不知道如何使用它。

我喜欢 DI(不仅在 Angular 中,而且在一般情况下)的一个事实是,您可以列出组件的依赖项,并且您不会为这种依赖项是如何构建的而烦恼。这对我来说非常重要,尤其是 Angular 中的 DI 允许您解析两种类型的组件:这些来自框架本身(如 $http ),或自定义组件(如我最喜欢的 eventBus,我用它来包装$on 事件处理程序)。

我经常查看服务的声明,我只通过查看依赖关系就知道它做了什么以及它是如何做的!

如果我要构建和/或使用组件本身深处的所有这些对象,那么我将始终必须彻底分析实现并从各个方面检查它。如果我看到 localStorage在依赖项列表中,我知道我正在使用 HTML5 本地存储来保存一些数据。我不必在代码中寻找它。

组件生命周期

我们不再需要担心某些组件的初始化顺序。如 A依赖于 B然后 DI 将确保 B准备好时 A需要它。

单元测试

在使用 DI 时模拟组件很有帮助。例如,如果您有 Controller :function Ctrl($scope, a, b, c, d)然后你立即知道它依赖什么。您注入(inject)适当的模拟,并确保所有与您交谈和聆听您的 Controller 的各方都是隔离的。如果您在编写测试时遇到麻烦,那么您很可能搞砸了抽象级别或违反了设计原则(直径定律、封装等)

好习惯

是的,很可能您可以使用命名空间来正确管理对象的生命周期。在需要的地方定义单例,并确保没有人弄乱您的私有(private)成员。
但老实说,如果框架可以为你做,你会需要吗?
直到我学会了 Angular,我才“以正确的方式”使用 JS。并不是我不在乎,我只是没有必要,因为我只是在几个星期的 UI 中使用 JS,主要基于 jquery。

现在它不同了,我得到了一个很好的框架,它迫使我有点跟上良好的实践,但它也给了我很大的能力来扩展它并利用 JS 的最佳特性。

当然,可怜的程序员仍然可以打破最好的工具,但从我最近阅读 D. Crockford 的“JS 的好部分”所学到的知识,人们正在用它做一些令人讨厌的事情。多亏了 jQuery、Angular 等优秀工具,我们现在有了一些不错的工具,可以帮助编写好的 JS 应用程序并在这样做时坚持最佳实践。

结论

正如您所指出的,您至少可以通过做以下三件事来编写好的 JS 应用程序:

  • 命名空间 - 这避免向全局命名空间添加内容,避免潜在的冲突并允许在需要时轻松解析适当的组件
  • 创建可重用的组件/模块 - 例如,通过使用功能模块模式并显式声明私有(private)和公共(public)成员
  • 管理组件之间的依赖关系 - 通过定义单例,允许从某些“注册表”中检索依赖关系,当某些条件不满足时不允许做某些事情

  • Angular 只是通过以下方式做到这一点:
  • $injector管理组件之间的依赖关系并在需要时检索它们
  • 强制使用具有 PRIVATE 和 PUBLIC API 的工厂函数。
  • 让组件直接(通过相互依赖)或共享 $scope 相互通信链。
  • 关于angularjs - AngularJS 依赖注入(inject)有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16792524/

    相关文章:

    angularjs - 如何使用 Angular 指令处理单个 HTML 元素上的多个触摸事件

    angularjs - 如何使用 $exceptionHandler 获取异常的所有详细信息,包括 errorMsg、url 和 lineNumber?

    c# - 为什么我的通用服务会收到错误 "Cannot instantiate implementation type"?

    c# - 在被动 View 架构中,我应该在哪里为 Presenter 类创建依赖项?

    python - 使用 DDD 和 Python 的大型服务器应用程序?

    javascript - 使用 Sinon.js 为 Angular.js 应用程序设置 RESTful 后端模拟

    javascript - 使用 Protractor 在angular js中进行文件上传测试

    javascript - 从 Angular 指令获取参数

    java - 使用接口(interface)注入(inject),同时必须创建底层对象的实例

    c# - 生命周期范围由 IoC 容器处理的单元测试对象