14

这是我在创建 AngularJS 应用程序时一直在考虑的问题。当我第一次了解 AngularJS 工厂时,我认为它们的一个巧妙用法是创建并返回构造函数而不是普通对象,例如:

app.factory("Foo", function() {
  function Foo(bar, baz) {
    this.bar = bar;
    this.baz = baz;
    ...
  }

  Foo.prototype = {
    constructor: Foo,
    method1: function() { ... },
    method2: function() { ... },
    ...,
    methodn: function() { ... },
  };

  return Foo;
});

然后,您可以将该函数注入您的控制器并使用new. 我发现这在美学上令人愉悦且面向对象,但现在我开始认为它实际上是一种反模式。问题是当你在支持 AngularJS 的上下文中工作时它工作得很好,但是一旦你想从控制台调用构造函数,在 Web Worker 中使用它,或者在非AngularJS 应用程序,您开始不得不围绕AngularJS 工作,而不是使用它。我开始怀疑这种方法是否被误导,因为 javascript 中的函数似乎已经是“单例”并且似乎不需要任何帮助来实例化。

我在滥用 AngularJS 工厂吗?我会更好地使用暴露于全局范围的构造函数吗?更一般地说,是否有特定因素促进 AngularJS 工厂/服务/提供者在全局对象上的使用,反之亦然?

4

2 回答 2

6

是的!

工厂语法:module.factory('factoryName', function); 结果:当将 factoryName 声明为可注入参数时,您将获得通过调用传递给 module.factory 的函数引用返回的值。用法:对于返回一个“类”函数可能很有用,然后可以新建该函数以创建实例。

来源:https ://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J

上面的链接也用作Bart评论的来源:AngularJS: Service vs provider vs factory

于 2013-11-21T00:48:14.690 回答
0

也许这在 Angular 和 Javascript 的上下文中是一个很好且方便的使用(它恰好允许对构造函数和对象原型进行令人难以置信的操作),但是,在我看来,它与经典的工厂模式逻辑有些矛盾。

工厂旨在在其中构造新对象,应用一些配置、初始化并将依赖项注入到新创建的对象中,如工厂设置中指定的(如果有的话)。

例如,你可以要求工厂创建存储连接,工厂创建 MySQL 连接、SQLite 连接或 Redis 连接——你的控制器并不关心,只要构造的对象实现一些接口(或使用鸭子-在 Javascript 上下文中输入 - 如果它像鸭子一样嘎嘎叫,那就是鸭子)。

但是如果你new在调用了一个在工厂外工作的工厂之后使用关键字,那么就好像你在说以下内容:

“嘿,工厂,给我一个项目的原型(构造器),我会自己创建项目。”

因此,在这种情况下,您的工厂不是用于创建新对象的“经典工厂”,而是一些原型工厂,它有一个原型提供给所有调用者,以便他们自己制造新对象。

当您有没有任何参数的简单构造函数时,您可能会接受,但在经典示例(存储连接)中,这种工厂的使用没有意义,因为工厂的调用者必须完成工厂的工作- 将配置和依赖项注入新创建的对象。

于 2018-02-16T12:01:45.100 回答