提问



据我了解,当在工厂内部时,我返回一个被注入控制器的对象。在服务内部时,我使用this处理对象而不返回任何内容。


我假设服务总是单身,并且新工厂对象被注入每个控制器。然而,事实证明,工厂对象也是单身人士?


用于演示的示例代码:


var factories = angular.module('app.factories', []);
var app = angular.module('app',  ['ngResource', 'app.factories']);

factories.factory('User', function () {
  return {
    first: 'John',
    last: 'Doe'
  };
});

app.controller('ACtrl', function($scope, User) {
  $scope.user = User;
});

app.controller('BCtrl', function($scope, User) {
  $scope.user = User;
});


当改变ACtrl中的user.first时,BCtrl中的user.first也被改变,例如User是单身人士?


我的假设是在一个带有工厂的控制器中注入了一个新实例?

最佳参考


所有角度服务都是单身:


文档(请参阅服务作为单身人士):https://docs.angularjs.org/guide/services [105]



  最后,重要的是要意识到所有Angular服务都是应用程序单例。这意味着每个注入器只有一个给定服务的实例。



基本上服务和工厂之间的区别如下:


app.service('myService', function() {

  // service is just a constructor function
  // that will be called with 'new'

  this.sayHello = function(name) {
     return "Hi " + name + "!";
  };
});

app.factory('myFactory', function() {

  // factory returns an object
  // you can run some code before

  return {
    sayHello : function(name) {
      return "Hi " + name + "!";
    }
  }
});


查看有关$ offer的演示文稿:http://slides.wesalvaro.com/20121113/#/[106]


这些幻灯片用于其中一个AngularJs聚会:http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html [107]

其它参考1


对我而言,当我意识到他们都以同样的方式工作时,我会发现这一点:通过运行一次,存储他们获得的价值,然后咳出相同的存储值通过依赖注入引用。


说我们有:


app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);


三者之间的区别在于:



  1. a存储的值来自运行fn,换句话说:fn()

  2. b的储值来自new fn,换句话说:new fn()

  3. c的存储值来自首先通过new fn获取实例,然后运行实例的$get方法



这意味着,就像角度内的缓存对象一样,每次注入的值只分配一次,当它们第一次被注入时,其中:


cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()


这就是我们在服务中使用this并在提供者中定义this.$get的原因。


希望这可以帮助。

其它参考2


实例



你好世界的例子



factory/service/provider:[108]


var myApp = angular.module('myApp', []);

//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});

//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!"
        }
    };
});

//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {
    // In the provider function, you cannot inject any
    // service or factory. This can only be done at the
    // "$get" method.

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});


function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {

    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}​

其它参考3


还有一种方法可以返回构造函数,以便您可以在工厂中返回 newable 类,如下所示:


function MyObjectWithParam($rootScope, name) {
  this.$rootScope = $rootScope;
  this.name = name;
}
MyObjectWithParam.prototype.getText = function () {
  return this.name;
};

App.factory('MyObjectWithParam', function ($injector) {
  return function(name) { 
    return $injector.instantiate(MyObjectWithParam,{ name: name });
  };
}); 


所以你可以在一个使用MyObjectWithParam的控制器中完成这个:


var obj = new MyObjectWithParam("hello"),


在这里看到完整的例子:

http://plnkr.co/edit/GKnhIN?p=preview[109]


在这里谷歌组页面,讨论的地方:
点击
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ [110]

其它参考4


以下是主要差异:


服务



语法:module.service( 'serviceName', function );


结果:当将serviceName声明为可注入参数时,将向您提供传递给module.service函数实例


用法:对于共享实用程序函数非常有用,只需将()附加到注入的函数引用即可调用。也可以injectedArg.call( this )或类似的方式运行。


工厂



语法:module.factory( 'factoryName', function );


结果:当将factoryName声明为可注入参数时,将提供通过调用传递给module.factory的函数引用返回的值。


用法:可用于返回class函数,然后可以将其设置为ed以创建实例。


还要检查AngularJS文档和stackoverflow上关于服务与工厂混淆的类似问题。[111]


这是使用服务和工厂的示例。阅读更多关于AngularJS服务与工厂的信息。[113] [114]

其它参考5


添加到第一个答案,我认为.service()适用于以更面向对象的方式编写代码的人(C#/Java)(使用此关键字并通过prototype/Constructor函数实例化对象)。


工厂适用于编写代码的开发人员,这些代码对于javascript/功能编码风格更为自然。


看看angular.js里面的.service和.factory方法的源代码 - 在内部它们都调用provider方法:


  function provider(name, provider_) {
    if (isFunction(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw Error('Provider ' + name + ' must define $get factory method.');
    }
    return providerCache[name + providerSuffix] = provider_;
  }

  function factory(name, factoryFn) { \
    return provider(name, { $get: factoryFn }); 
  }

  function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }

其它参考6


非常简单:


.service - 注册函数将作为构造函数调用(又名newed)


.factory - 注册函数将被调用为一个简单的函数


两次调用都会导致单个对象被注入到应用程序的其他组件中。

其它参考7


所有提供商的工作方式相同。不同的方法servicefactoryprovider只是让你在更少的代码中完成同样的事情。


附:还有valueconstant


provider开头并以value开头的链中的每个特殊情况都有一个附加限制。因此,要在它们之间做出决定,你必须问问自己哪个让你用更少的代码完成你想要的东西。


这是一张图片,向您展示我的意思:


[115]


您可以在博客文章中找到细分和参考指南,我从以下网址获得此图片:


http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/[116]

其它参考8


以下是服务与工厂的更多示例,这些示例可能有助于了解它们之间的差异。基本上,一个服务有new ...调用它,它已经被实例化了。工厂不会自动实例化。




基本示例



返回一个具有单个方法的类对象



这是一个具有单一方法的服务:


angular.service('Hello', function () {
  this.sayHello = function () { /* ... */ };
});


这是一个使用方法返回对象的工厂:


angular.factory('ClassFactory', function () {
  return {
    sayHello: function () { /* ... */ }
  };
});


返回值



返回数字列表的工厂:


angular.factory('NumberListFactory', function () {
  return [1, 2, 3, 4, 5];
});

console.log(NumberListFactory);


返回数字列表的服务:


angular.service('NumberLister', function () {
  this.numbers = [1, 2, 3, 4, 5];
});

console.log(NumberLister.numbers);


两种情况下的输出都是相同的,即数字列表。


高级示例



使用工厂的类变量



在这个例子中,我们定义了一个CounterFactory,它递增或递减一个计数器,你可以获得当前计数或获取已创建的CounterFactory对象的数量:


angular.factory('CounterFactory', function () {
  var number_of_counter_factories = 0; // class variable

  return function () {
    var count = 0; // instance variable
    number_of_counter_factories += 1; // increment the class variable

    // this method accesses the class variable
    this.getNumberOfCounterFactories = function () {
      return number_of_counter_factories;
    };

    this.inc = function () {
      count += 1;
    };
    this.dec = function () {
      count -= 1;
    };
    this.getCount = function () {
      return count;
    };
  }

})


我们使用CounterFactory创建多个计数器。我们可以访问类变量来查看创建了多少个计数器:


var people_counter;
var places_counter;

people_counter = new CounterFactory();
console.log('people', people_counter.getCount());
people_counter.inc();
console.log('people', people_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());

places_counter = new CounterFactory();
console.log('places', places_counter.getCount());

console.log('counters', people_counter.getNumberOfCounterFactories());
console.log('counters', places_counter.getNumberOfCounterFactories());


此代码的输出是:


people 0
people 1
counters 1
places 0
counters 2
counters 2

其它参考9


工厂和服务是角度进行DI(依赖注入)的不同方式。


因此,当我们使用服务定义DI时,如下面的代码所示。这将创建Logger对象的新GLOBAL实例并将其注入函数。


app.service("Logger", Logger); // Injects a global object


使用工厂定义DI时,它不会创建实例。它只是传递方法,后来消费者在内部必须为工厂调用对象实例。


app.factory("Customerfactory", CreateCustomer);


下面是一个简单的图像,直观地显示了服务的DI过程与工厂的不同之处。





当我们想要根据场景创建不同类型的对象时,应该使用工厂。例如,取决于我们想要创建简单的客户对象的场景,或者具有地址对象的客户或具有电话对象的客户。以下是本段的详细解释[117]


应该使用服务当我们有实用程序或共享函数被注入时,如Utility,Logger,Error handler等。

其它参考10


服务样式:(可能是最简单的)返回实际函数:用于共享实用函数,通过简单地将()附加到注入的函数引用来调用它。


AngularJS中的服务是一个单独的JavaScript对象,它包含一组函数


var myModule = angular.module("myModule", []);

myModule.value  ("myValue"  , "12345");

function MyService(myValue) {
    this.doIt = function() {
        console.log("done: " + myValue;
    }
}

myModule.service("myService", MyService);
myModule.controller("MyController", function($scope, myService) {

    myService.doIt();

});


工厂样式:(更多参与但更复杂的)返回函数的返回值:在java中实例化一个像新Object()的对象。


工厂是一个创造价值的功能。当服务,控制器等需要从工厂注入的值时,工厂按需创建值。一旦创建,该值将重用于需要注入的所有服务,控制器等。


var myModule = angular.module("myModule", []);

myModule.value("numberValue", 999);

myModule.factory("myFactory", function(numberValue) {
    return "a value: " + numberValue;
})  
myModule.controller("MyController", function($scope, myFactory) {

    console.log(myFactory);

});


提供程序样式:(完整版,可配置版)返回函数s $ get function:Configurable的输出。


AngularJS中的提供商是您可以创建的最灵活的工厂形式。除了使用provider()函数之外,您可以像使用服务或工厂一样向模块注册提供程序。


var myModule = angular.module("myModule", []);

myModule.provider("mySecondService", function() {
    var provider = {};
    var config   = { configParam : "default" };

    provider.doConfig = function(configParam) {
        config.configParam = configParam;
    }

    provider.$get = function() {
        var service = {};

        service.doService = function() {
            console.log("mySecondService: " + config.configParam);
        }

        return service;
    }

    return provider;
});

myModule.config( function( mySecondServiceProvider ) {
    mySecondServiceProvider.doConfig("new config param");
});

myModule.controller("MyController", function($scope, mySecondService) {

    $scope.whenButtonClicked = function() {
        mySecondService.doIt();
    }

});


src jenkov [118]




<!DOCTYPE html>
    <html ng-app="app">
    <head>
    	<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
    	<meta charset=utf-8 />
    	<title>JS Bin</title>
    </head>
    <body ng-controller="MyCtrl">
    	{{serviceOutput}}
    	<br/><br/>
    	{{factoryOutput}}
    	<br/><br/>
    	{{providerOutput}}
    
    	<script>
    
    		var app = angular.module( 'app', [] );
    
    		var MyFunc = function() {
    
    			this.name = "default name";
    
    			this.$get = function() {
    				this.name = "new name"
    				return "Hello from MyFunc.$get(). this.name = " + this.name;
    			};
    
    			return "Hello from MyFunc(). this.name = " + this.name;
    		};
    
    		// returns the actual function
    		app.service( 'myService', MyFunc );
    
    		// returns the function's return value
    		app.factory( 'myFactory', MyFunc );
    
    		// returns the output of the function's $get function
    		app.provider( 'myProv', MyFunc );
    
    		function MyCtrl( $scope, myService, myFactory, myProv ) {
    
    			$scope.serviceOutput = "myService = " + myService;
    			$scope.factoryOutput = "myFactory = " + myFactory;
    			$scope.providerOutput = "myProvider = " + myProv;
    
    		}
    
    	</script>
    
    </body>
    </html>



基本区别在于, provider 允许将原始(非对象),数组或回调函数值设置为工厂声明的变量,因此如果返回一个对象,则必须显式声明并返回。


另一方面, service 只能用于将服务声明变量设置为对象,因此我们可以避免显式创建和返回对象,而另一方面它允许使用此关键字。


或者简而言之, provider 是一种更通用的形式,而服务仅限于对象。

其它参考11


这就是我如何理解它们在设计模式方面的区别:


服务:返回一个类型,该类型将被新建以创建该类型的对象。如果使用Java类比,则Service返回 Java类定义


工厂:返回可以立即使用的具体对象。在Java类比中,工厂返回 Java对象


经常使人(包括我自己)感到困惑的部分是,当您在代码中注入服务或工厂时,它们可以以相同的方式使用,在两种情况下您在代码中获得的内容都是可以立即调用的具体对象。这意味着在服务的情况下,角度代表您在服务声明上调用新。我认为这是一个令人费解的概念。

其它参考12


AngularJS服务与工厂



module.service( 'serviceName', function );

module.factory( 'factoryName', function );


serviceName声明为injectable参数时,将为您提供该函数的实例。换句话说,新FunctionYouPassedToService()。如果需要,该对象实例将成为AngularJS注册并稍后注入其他services / controllers的服务对象。[119]


factoryName声明为injectable参数时,将通过调用传递给module.factory的函数引用来提供返回的值。


在下面的例子中,我们以两种不同的方式定义MyService。请注意.service中如何使用this.methodname创建服务方法。在.factory中,我们创建了一个工厂对象并为其分配了方法。


AngularJS .service


module.service('MyService', function() {
    this.method1 = function() {
            //..
        }

    this.method2 = function() {
            //..
        }
});


AngularJS .factory


module.factory('MyService', function() {

    var factory = {}; 

    factory.method1 = function() {
            //..
        }

    factory.method2 = function() {
            //..
        }

    return factory;
});

其它参考13


我们可以定义这样的服务:


app.service('MyService', function () {
   this.sayHello = function () {
      console.log('hello');
   };
});


.service()是我们模块上的一个方法,它采用名称和定义服务的函数。很直接。一旦定义,我们就可以在其他组件中注入和使用该特定服务,例如控制器,指令和过滤器,如下所示:


现在和工厂一样:


app.factory('MyService', function () {
    return {
       sayHello: function () {
           console.log('hello');
       }
    }
});


同样,.factory()是我们模块上的一个方法,它还有一个名称和一个定义工厂的函数。我们可以完全按照与服务相同的方式注入和使用该东西。现在这有什么区别?


好吧,你可能会看到,而不是在工厂中使用它,我们返回一个对象文字。这是为什么?事实证明,服务是构造函数而工厂不是。在这个Angular世界的深处,有这个代码在实例化时使用服务构造函数调用Object.create()。但是,工厂函数实际上只是一个被调用的函数,这就是我们必须显式返回一个对象的原因。

其它参考14


这将是了解Service Vs Factory Vs Provider的最佳和简短的答案


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


这里 ben 演示 http://jsbin.com/ohamub/1/edit?html,output[121]表示


代码中有评论说明了主要区别,但我会在这里稍微扩展一下。作为一个说明,我只是想了解这一点,所以如果我说出任何错误,请告诉我。


服务


语法:module.service(serviceName,function);


结果:将serviceName声明为injectable参数时,将提供传递给module.service的实际函数引用。


用法:通过简单地向注入的函数引用附加()来共享对调用有用的实用程序函数可能很有用。也可以使用injectArg.call(this)或类似的方式运行。


工厂


语法:module.factory(factoryName,function);


结果:将factoryName声明为injectable参数时,将通过调用传递给module.factory的函数引用来提供返回的值。


用法:对于返回类函数非常有用,该函数可以是新的ed来创建实例。


提供商


语法:module.provider(providerName,function);


结果:将providerName声明为injectable参数时,将通过调用传递给module.provider的函数引用的$ get方法来提供返回的值。


用法:对于返回一个类函数非常有用,该函数可以是新的ed来创建实例,但在注入之前需要某种配置。对于可跨项目重用的类可能有用吗?这个还是有些朦胧。


其它参考15


我有一段时间的困惑,我在这里尽力提供一个简单的解释。希望这会有所帮助!


angular .factoryangular .service都用于初始化服务并以相同的方式工作。


唯一的区别是,您希望如何初始化服务。


两人都是单身人士





var app = angular.module('app', []);








app.factory(<service name><function with a return value>)



如果您想从具有返回值的函数初始化您的服务,则必须使用此factory方法。


例如


function myService() {
  //return what you want
  var service = {
    myfunc: function (param) { /* do stuff */ }
  }
  return service;
}

app.factory('myService', myService);


注入此服务时(例如,向您的控制器):



  • Angular将调用您的给定函数(作为myService())以返回对象

  • Singleton - 只调用一次,存储并传递相同的对象。







服务



app.service(<service name><constructor function>)



如果您想从构造函数(使用this关键字)初始化您的服务,则必须使用此service方法。


例如


function myService() {
  this.myfunc: function (param) { /* do stuff */ }
}

app.service('myService', myService);


注入此服务时(例如,向您的控制器):



  • Angular会new你的给定函数(如new myService())返回对象

  • Singleton - 只调用一次,存储并传递相同的对象。





注意:如果将factory<constructor function>service一起使用<function with a return value>,则无效。





示例 - DEMOs




  • Angular Service vs Factory

  • 角度服务与工厂(带路线)


其它参考16


由于Pascal Precht的博客文章,这有助于我理解其中的差异。[122] [123]


服务是模块上的一种方法,它采用名称和定义服务的函数。您可以在其他组件中注入和使用该特定服务,例如控制器,指令和过滤器。工厂是模块上的方法,它还采用名称和函数来定义工厂。我们也可以像使用服务一样注入和使用它。


用new创建的对象使用构造函数的prototype属性的值作为它们的原型,所以我找到了调用Object.create()的Angular代码,我相信它是实例化时的服务构造函数。但是,工厂函数实际上只是一个被调用的函数,这就是为什么我们必须返回工厂的对象文字。


这是我为工厂找到的1.5角度代码:


var needsRecurse = false;
    var destination = copyType(source);

    if (destination === undefined) {
      destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
      needsRecurse = true;
    }


factory()函数的Angular源代码片段:


 function factory(name, factoryFn, enforce) {
    return provider(name, {
      $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
    });
  }


它接受传递的名称和工厂函数,并返回一个具有相同名称的提供程序,它具有$ get方法,这是我们的工厂函数。每当您向注入器询问特定的依赖项时,它通常通过调用$ get()方法向相应的提供程序询问该服务的实例。这就是创建提供者时需要$ get()的原因。


这是用于服务的角度1.5代码。


function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
  }


事实证明,当我们调用service()时,它实际上调用了factory()!但是,它不仅仅将我们的服务构造函数传递给工厂。它还传递一个函数,该函数要求注入器通过给定的构造函数实例化对象。


换句话说,如果我们在某处注入MyService,代码中会发生以下情况:


MyServiceProvider.$get(); // return the instance of the service


要重新进行重新设置,服务会调用工厂,这是相应提供程序上的$ get()方法。而且,$ injector.instantiate()是最终使用构造函数调用Object.create()的方法。这就是我们在服务中使用this的原因。


对于ES5,无论我们使用哪个:service()或factory(),它都是一个被调用的工厂,它为我们的服务创建了一个提供者。


尽管如此,您也可以使用相同的服务。服务是构造函数,但是,它不会阻止我们返回对象文字。因此,我们可以使用我们的服务代码并以基本上与我们的工厂完全相同的方式编写它,换句话说,您可以将服务编写为工厂以返回对象。


为什么大多数人建议使用工厂而不是服务?这是我见过的最好的答案,它来自Pawel Kozlowski的书:使用AngularJS掌握Web应用程序开发。



  工厂方法是获取对象的最常用方法
  AngularJS依赖注入系统。它非常灵活,可以
  包含复杂的创建逻辑。由于工厂是正规的
  功能,我们也可以利用新的词法范围
  模拟私人变量。这非常有用,因为我们可以隐藏
  给定服务的实现细节。


其它参考17



  • 使用工厂,您实际上会在工厂内创建对象并将其返回。

  • 使用服务,您只需使用 this关键字来定义标准功能
    功能

  • 使用提供程序,您定义了$get,可以使用来获取返回的对象
    数据。


其它参考18


在AngularJS中有三种处理业务逻辑的方法:(受Yaakov的Coursera AngularJS课程启发),它们是:



  1. 服务


  2. 提供商



在这里,我们只讨论服务工厂


SERVICE :


语法:


app.js


 var app = angular.module('ServiceExample',[]);
 var serviceExampleController =
              app.controller('ServiceExampleController', ServiceExampleController);
 var serviceExample = app.service('NameOfTheService', NameOfTheService);

 ServiceExampleController.$inject = ['NameOfTheService'] //very important as this protects from minification of js files

function ServiceExampleController(NameOfTheService){
     serviceExampleController = this;
     serviceExampleController.data = NameOfTheService.getSomeData();
 }

function NameOfTheService(){
     nameOfTheService = this;
     nameOfTheService.data = "Some Data";
     nameOfTheService.getSomeData = function(){
           return nameOfTheService.data;
     }     
}


的index.html


<div ng-controller = "ServiceExampleController as serviceExample">
   {{serviceExample.data}}
</div>


服务的主要特点:



  1. Lazily Instantiated :如果没有注入服务,它就不会被实例化。所以要使用它,你必须将它注入模块。

  2. Singleton :如果将其注入多个模块,则所有模块都可以访问o只是一个特定的例子。这就是为什么在不同控制器之间共享数据非常方便。



FACTORY


现在让我们谈谈AngularJS中的工厂


首先让我们看一下语法:


app.js :


var app = angular.module('FactoryExample',[]);
var factoryController = app.controller('FactoryController', FactoryController);
var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne);
var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo);

//first implementation where it returns a function
function NameOfTheFactoryOne(){
   var factory = function(){
      return new SomeService();
    }
   return factory;
}

//second implementation where an object literal would be returned
function NameOfTheFactoryTwo(){
   var factory = {
      getSomeService : function(){
          return new SomeService();
       }
    };
   return factory;
}


现在在控制器中使用以上两个:


 var factoryOne = NameOfTheFactoryOne() //since it returns a function
 factoryOne.someMethod();

 var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
 factoryTwo.someMethod();


工厂特点:



  1. 此类服务遵循工厂设计模式。可以将工厂视为创建新对象或方法的中心位置。

  2. 这不仅可以生成单例,还可以生成可自定义的服务。

  3. .service()方法是工厂,它始终生成相同类型的服务,即单例。没有简单的方法来配置它的行为。.service()方法通常被用作不需要任何配置的东西的快捷方式。


其它参考19


有关简短说明,请参阅https://stackoverflow.com/a/26924234/5811973。


有关详细说明,请参阅https://stackoverflow.com/a/15666049/5811973。


也来自angularJs文档:
[126]

其它参考20


你可以理解这个类比的区别 - 考虑一个将返回一些值的普通函数和将使用new keyword实例化的构造函数之间的区别。所以创建工厂就像创建将返回一些值的原始函数(原始或一个对象)而创建服务就像创建构造函数(OO类),我们可以使用new关键字创建实例。唯一需要注意的是,当我们使用Service方法创建服务时,它将使用AngularJS支持的依赖注入机制自动创建它的实例