javascript AngularJS 设计模式:我应该使用工厂来创建构造函数吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18072683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS design patterns: Should I use factories to create constructor functions?
提问by brainkim
This is something I've been mulling over while creating an AngularJS app. When I first learned about AngularJS factories, I thought one clever usage of them would be to create and return a constructor function rather than a plain object, i.e. something like:
这是我在创建 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;
});
Then, you could inject the function into your controllers and call it with new
. I found this aesthetically pleasing and OOP-y, but now I'm starting to think that it's actually an anti-pattern. The problem is that it works fine for when you're working within AngularJS-aware contexts, but once you want to, for instance, call the constructor from the console, use it in a Web Worker, or reuse the code in a non-AngularJS app, you start having to work aroundAngularJS rather than with it. I began to wonder if this approach was misguided insofar as functions in javascript already seem to be "singletons" and don't seem to need any help being instantiated.
然后,您可以将该函数注入控制器并使用new
. 我发现这在美学上令人愉悦且 OOP-y,但现在我开始认为它实际上是一种反模式。问题是当你在 AngularJS 感知上下文中工作时它工作正常,但是一旦你想要,例如,从控制台调用构造函数,在 Web Worker 中使用它,或者在非AngularJS 应用程序,你开始不得不围绕AngularJS工作,而不是使用它。我开始怀疑这种方法是否被误导了,因为 javascript 中的函数似乎已经是“单例”并且似乎不需要任何帮助来实例化。
Am I misusing AngularJS factories? Would I be better served with constructor functions exposed to the global scope? More generally, are there specific factors which promote the usage of AngularJS factories/services/providers over global objects or vice versa?
我是否在滥用 AngularJS 工厂?暴露于全局作用域的构造函数会更好地为我服务吗?更一般地说,是否有特定因素促进了 AngularJS 工厂/服务/提供者在全局对象上的使用,反之亦然?
回答by Al Johri
Yes!
是的!
Factories Syntax: module.factory( 'factoryName', function ); Result: When declaring factoryName as an injectable argument you will be provided the value that is returned by invoking the function reference passed to module.factory. Usage: Could be useful for returning a 'class' function that can then be new'ed to create instances.
工厂语法:module.factory( 'factoryName', function ); 结果:当将 factoryName 声明为可注入参数时,您将获得通过调用传递给 module.factory 的函数引用返回的值。用法:对于返回一个“类”函数可能很有用,然后可以将其新建以创建实例。
Source: https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J
来源:https: //groups.google.com/forum/#!msg/ angular/56sdORWEoqg/ HuZsOsMvKv4J
The above link is also used as the source to Bart'scomment: AngularJS: Service vs provider vs factory
上面的链接也被用作Bart评论的来源:AngularJS: Service vs provider vs factory
回答by JustAMartin
Maybe this is a nice and convenient use in context of Angular and Javascript (which happens to allow mind boggling manipulations with constructors and object prototypes), but, in my opinion, it somewhat contradicts classical Factory pattern logic.
也许这在 Angular 和 Javascript 的上下文中是一个很好且方便的用法(碰巧允许使用构造函数和对象原型进行令人难以置信的操作),但是,在我看来,它有点与经典的工厂模式逻辑相矛盾。
Factory is meant to construct new objects inside of it, applying some configuration, initialization and injecting dependencies into the newly created object, as specified in factory settings (if you have any).
工厂旨在在其中构建新对象,应用一些配置、初始化并将依赖项注入新创建的对象,如工厂设置(如果有的话)中指定的那样。
For example, you can ask a factory to create a storage connection, and the factory creates a MySQL connection, SQLite connection or Redis connection - your controller doesn't really care, as long as the constructed object implements some interface (or use duck-typing in Javascript context - if it quacks like a duck, it is a duck).
例如,你可以要求一个工厂创建一个存储连接,工厂创建一个 MySQL 连接、SQLite 连接或 Redis 连接——你的控制器并不真正关心,只要构造的对象实现了一些接口(或使用duck-在 Javascript 上下文中输入 - 如果它像鸭子一样嘎嘎叫,它就是一只鸭子)。
But if you use new
keyword after you have called a Factory working outside of the Factory, then it's as if you say the following:
但是,如果您new
在调用了在工厂外工作的工厂之后使用关键字,那么就好像您在说以下内容:
"Hey, factory, give me a prototype (constructor) of some item and I will create the item myself."
“嘿,工厂,给我一些物品的原型(构造函数),我会自己制作物品。”
So, in this case your factory is not a "classical factory" for creating new objects but some prototype factory that has one prototype to provide to all callers so they can themselves manufacture new objects.
因此,在这种情况下,您的工厂不是用于创建新对象的“经典工厂”,而是一些原型工厂,该工厂具有一个原型以提供给所有调用者,以便他们自己制造新对象。
When you have simple constructors without any arguments, you might be ok with that, but in the classical example (the storage connection) such use of factories doesn't make sense because then the caller of the factory has to do the job of the factory - inject configurations and dependencies into the newly created object.
当你有没有任何参数的简单构造函数时,你可能会接受,但在经典示例(存储连接)中,这样使用工厂是没有意义的,因为工厂的调用者必须完成工厂的工作- 将配置和依赖项注入到新创建的对象中。