8

我使用 Angular 已经有一段时间了,但我看不出它是如何比我以前的编码方式有所改进的。

首先,我看不出有一个中心对象来保存你的项目有什么问题。毕竟,注入器是一个单例,它将你的依赖项查找到一个中心位置,所以 Angular 确实有一个中心对象,它只是被隐藏了。命名空间并不一定意味着耦合,如果它做得正确的话。即使完成了,您也不需要代码的每个对象都与其他对象松散耦合。此外,任何时候你创建一个独立的 JS 脚本,你都必须将它包装到 Angular 中,以使它们能够很好地协同工作。

其次,每次都声明所有依赖项非常冗长(尤其是在缩小时),因此与正确的命名空间相比,从可读性的角度来看没有任何好处。

第三,性能增益很小。它迫使我在任何地方都使用单例,但如果需要,我可以自己做,而且大多数时候我不需要(网络和 DOM 操作是我的瓶颈,而不是 JS 对象)。

最后,我喜欢“增强的”HTML 和自动双向绑定,但我看不出注入如何使它比其他框架处理依赖项的方式更好,因为它甚至不提供动态像 require.js 一样加载。我没有看到任何用例在编码时对自己说“哦,这比以前好多了,我明白了”。

您能否向我解释一下这种技术选择给项目带来了什么好处?

我现在只能看到一个:惯例和最佳实践执行。创建一个 lib 生态系统是一件大事,但目前我在 Angular 社区中还没有看到它的成果。

4

1 回答 1

7

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

统一的、声明性的依赖解析

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

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

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

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

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

组件的使用寿命

我们不再需要为某些组件的初始化顺序而烦恼。如果A依赖,B那么 DI 将确保B在需要时准备好A

单元测试

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

好习惯

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

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

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

结论

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

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

Angular 只是通过以下方式做到这一点:

  • 拥有$injectorwhich 管理组件之间的依赖关系并在需要时检索它们
  • 强制使用同时具有 PRIVATE 和 PUBLIC API 的工厂函数。
  • 让组件直接(通过相互依赖)或通过共享$scope链相互通信。
于 2013-06-05T16:36:59.537 回答