Help us understand the problem. What is going on with this article?

Angular.jsのServiceとFactoryの違いを考える

More than 5 years have passed since last update.

前回valueとfactoryの違いを考えたので、今回はServiceFactoryの違いを考えたいと思う。

違いはある?ない?

とりあえずFactoryを使っているという声も聞かれるが、例えば angular-ui/ng-gridGitHubのソースを見ると、下記のようなフォルダ構成になっていて、明示的に用途を分けている。

ng-grid_src_js_core_at_master_·_angular-ui_ng-grid_·_GitHub.png

どういう意図で分けているのか、まず、What is the difference between module.factory and module.service and how might both be applied?のスレッドに書かれてることを意訳したい。

Service

Services
Syntax: module.service( 'serviceName', function );
Result: When declaring serviceName as an injectable argument you will get an instance of the function. In other words new FunctionYouPassedToService().
Usage: Could be useful for sharing utility functions that are useful to invoke by simply appending () to the injected function reference.

Services
表記: module.service( 'serviceName', function );
結果: serviceNameを宣言した時点で、関数のインスタンスが生成される。別の書き方をするなら new FunctionYouPassedToService();
用法: 括弧"()"を付けるだけで参照したい共通関数などを共有する場合に適している。

Factory

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.

Factories
表記: module.factory('factoryName', function);
結果: factoryNameを宣言した時点で、module.factoryに渡している関数がreturnしている値が提供される。
用法: newでインスタンス化したいクラスがある場合に適している。

つまり

クラス化せずに、共通関数の束として使いたい場合はService。クラス化した方が便利なのであればFactoryということらしい。

サンプルソース

足し算と引き算をする簡単な例を作ってみる。

index.html
<!doctype html>
<html lang="jp" ng-app="App">
<head>
  <meta charset="utf-8">
  <script src="bower_components/angular/angular.js"></script>
  <script src="app.js"></script>
</head>
<body>
<div ng-controller="Ctrl">
  3+2-1={{answer_service}}<br/>
  3+2-1={{answer_factory}}
</div>
</body>
</html>
app.js
angular.module('App',[])
  .service('MyUtils', function(){
    var service = {
      add: function(a,b){ return a+b; },
      sub: function(a,b){ return a-b; }
    };
    return service;
  })
  .factory('MyMath', function(){
    function MyKlass(n){ this.n = n; }
    MyKlass.prototype.add = function(a){ this.n += a; return this; };
    MyKlass.prototype.minus = function(a){ this.n -= a; return this; };
    return MyKlass;
  })
  .controller('Ctrl',
    ["$scope", "MyUtils", "MyMath",
      function($scope, MyUtils, MyMath){
        // 関数群として呼び出す - Service
        $scope.answer_service = MyUtils.sub(MyUtils.add(3,2),1);
        // クラスとして呼び出す - Factory
        $scope.answer_factory = (new MyMath(3)).add(2).minus(1).n;
      }
    ]
  );
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした