Service vs Factory vs provider的迷惑

刚开始我很迷惑的,可是通过一段时间的项目,还有看大漠老师的东西,彷佛明白了,他们的区别也就是  一我的喜欢吃面仍是吃饭或者肯德基区别。目的就是填饱肚子!javascript

如下是它们在AngularJS源代码中的定义:java

1
2
3
4
5
6
7
8
9
function factory(name, factoryFn) {
     return provider(name, { $get: factoryFn });
}
 
function service(name, constructor) {
     return factory(name, [ '$injector' , function ($injector) {
       return $injector.instantiate(constructor);
     }]);
}

从源代码中你能够看到,service仅仅是调用了factory函数,然后者又调用了provider函数。事实上,AngularJS也为一些值、常量和装饰提供额外的provider封装,而这些并无致使相似的困惑,它们的文档都很是清晰。编程

因为service仅仅是调用了factory函数,这有什么区别呢?线索在$injector.instantiate:在这个函数中,$injector在service的构造函数中建立了一个新的实例。app

如下是一个例子,展现了一个service和一个factory如何完成相同的事情:ide

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var app = angular.module( 'app' ,[]);
 
app.service( 'helloWorldService' , function (){
     this .hello = function () {
         return "Hello World" ;
     };
});
 
app.factory( 'helloWorldFactory' , function (){
     return {
         hello: function () {
             return "Hello World" ;
         }
     }
});

当helloWorldService或helloWorldFactory被注入到控制器中,它们都有一个hello方法,返回”hello world”。service的构造函数在声明时被实例化了一次,同时factory对象在每一次被注入时传递,可是仍然只有一个factory实例。全部的providers都是单例。函数

既然能作相同的事,为何须要两种不一样的风格呢?相对于service,factory提供了更多的灵活性,由于它能够返回函数,这些函数以后能够被新建出来。这迎合了面向对象编程中工厂模式的概念,工厂能够是一个可以建立其余对象的对象。this

1
2
3
4
5
6
7
8
9
app.factory( 'helloFactory' , function () {
     return function (name) {
         this .name = name;
 
         this .hello = function () {
             return "Hello " + this .name;
         };
     };
});

这里是一个控制器示例,使用了service和两个factory,helloFactory返回了一个函数,当新建对象时会设置name的值。spa

1
2
3
4
5
6
7
8
9
app.controller( 'helloCtrl' , function ($scope, helloWorldService, helloWorldFactory, helloFactory) {
     init = function () {
       helloWorldService.hello(); //'Hello World'
       helloWorldFactory.hello(); //'Hello World'
       new helloFactory( 'Readers' ).hello() //'Hello Readers'
     }
 
     init();
});

在初学时,最好只使用service。设计

Factory在设计一个包含不少私有方法的类时也颇有用:code

1
2
3
4
5
6
7
8
9
10
11
app.factory( 'privateFactory' , function (){
     var privateFunc = function (name) {
         return name.split( "" ).reverse().join( "" ); //reverses the name
     };
 
     return {
         hello: function (name){
           return "Hello " + privateFunc(name);
         }
     };
});

经过这个例子,咱们可让privateFactory的公有API没法访问到privateFunc方法,这种模式在service中是能够作到的,但在factory中更容易。

相关文章
相关标签/搜索