AngularJSにおけるService、Provider、Factoryの比較とコード例

2024-08-31

AngularJSにおけるService、Provider、Factoryの違い

AngularJSのDependency Injection (依存性注入)

AngularJSでは、依存性注入という概念を用いて、オブジェクト間の依存関係を管理します。これにより、コードのモジュール化とテスト性を向上させることができます。

Service、Provider、Factoryの役割

これら3つの概念は、AngularJSのサービスを作成するための手段です。それぞれ異なるライフサイクルと使用方法を持ちます。

Service

  • ライフサイクル: アプリケーションの起動時にインスタンス化され、アプリケーションの終了まで存在します。
  • 用途: 汎用的なサービスや、アプリケーション全体で共有したいデータを保持するサービスに適しています。
  • 例:
angular.module('myApp', [])
  .service('myService', function() {
    var data = 'hello';
    this.getData = function() {
      return data;
    };
  });

Provider

  • ライフサイクル: アプリケーションの起動時にインスタンス化され、$getメソッドが呼ばれるまでは、設定や初期化の処理に使用されます。
  • 用途: サービスの初期化や設定をカスタマイズしたい場合、または、サービスのインスタンス化を遅延させたい場合に適しています。
angular.module('myApp', [])
  .provider('myProvider', function() {
    var baseUrl = 'http://example.com';

    this.setBaseUrl = function(newBaseUrl) {
      baseUrl = newBaseUrl;
    };

    this.$get = function() {
      return {
        getData: function() {
          return $http.get(baseUrl + '/data').then(function(response) {
            return response.data;
          });
        }
      };
    };
  });

Factory

  • 用途: Serviceと同様ですが、より柔軟なオブジェクトの返却が可能です。
angular.module('myApp', [])
  .factory('myFactory', function() {
    return {
      getData: function() {
        return 'hello';
      },
      otherMethod: function() {
        // ...
      }
    };
  });

いつどの概念を使うべきか

  • Service: 汎用的なサービスや、アプリケーション全体で共有したいデータを保持する場合。
  • Factory: 柔軟なオブジェクトを返したい場合、または、Serviceと同様の機能が必要な場合。



特徴ServiceProviderFactory
ライフサイクルアプリケーションの起動時にインスタンス化され、アプリケーションの終了まで存在する。アプリケーションの起動時にインスタンス化されるが、$getメソッドが呼ばれるまでは、設定や初期化の処理に使用される。Serviceと同じく、アプリケーションの起動時にインスタンス化され、アプリケーションの終了まで存在する。
用途汎用的なサービスや、アプリケーション全体で共有したいデータを保持するサービスに適している。サービスの初期化や設定をカスタマイズしたい場合、または、サービスのインスタンス化を遅延させたい場合に適している。Serviceと同様ですが、より柔軟なオブジェクトの返却が可能です。
返り値常にオブジェクトを返す。$getメソッドが返すオブジェクト。任意の値を返すことができる。

コード例

angular.module('myApp', [])
  .service('myService', function() {
    var data = 'hello';
    this.getData = function() {
      return data;
    };
  });
angular.module('myApp', [])
  .provider('myProvider', function() {
    var baseUrl = 'http://example.com';

    this.setBaseUrl = function(newBaseUrl) {
      baseUrl = newBaseUrl;
    };

    this.$get = function() {
      return {
        getData: function() {
          return $http.get(baseUrl + '/data').then(function(response) {
            return response.data;
          });
        }
      };
    };
  });
angular.module('myApp', [])
  .factory('myFactory', function() {
    return {
      getData: function() {
        return 'hello';
      },
      otherMethod: function() {
        // ...
      }
    };
  });

使用例




Class-based Services

AngularJS 1.5以降、クラスベースのサービスが導入されました。これは、ES6のクラス構文を使用してサービスを定義する方法です。

class MyService {
  constructor() {
    this.data = 'hello';
  }

  getData() {
    return this.data;
  }
}

angular.module('myApp', [])
  .service('myService', MyService);

Constant

constantは、アプリケーションの起動時に評価され、変更できない値を定義するためのものです。

angular.module('myApp', [])
  .constant('MY_CONSTANT', 'hello');

Value

angular.module('myApp', [])
  .value('myValue', 'hello');

Decorator

decoratorは、既存のサービスを装飾して、その挙動を変更するためのものです。

angular.module('myApp', [])
  .decorator('myService', function($delegate) {
    $delegate.getData = function() {
      return 'modified data';
    };
  });

Providerの直接使用

Providerは、サービスの初期化や設定をカスタマイズするためのものです。直接使用することもできます。

angular.module('myApp', [])
  .config(function(myProvider) {
    myProvider.setBaseUrl('http://new.example.com');
  });

$injector

$injectorは、サービスの取得や注入を行うためのAngularJSの組み込みサービスです。

angular.module('myApp', [])
  .controller('MyController', function($injector) {
    var myService = $injector.get('myService');
    // ...
  });

どの方法を使うべきか

  • Provider: サービスの初期化や設定をカスタマイズしたい場合。
  • Class-based Services: ES6のクラス構文を使用したい場合。
  • Constant: 変更できない値を定義する場合。
  • Value: 変更可能な値を定義する場合。
  • Decorator: 既存のサービスの挙動を変更する場合。
  • $injector: サービスの取得や注入を行う場合。

angularjs dependency-injection angularjs-service

angularjs dependency injection service

依存性注入 (Dependency Injection) の日本語解説

依存性注入 (Dependency Injection) とは、プログラミングにおける設計パターンの一つで、オブジェクトの依存関係を外部から注入することによって、コードの柔軟性とテスト可能性を高める手法です。依存関係: オブジェクトが他のオブジェクトの機能に依存している状態。


JavaBeanの基本とDI/IoCの代替手法 (日本語)

JavaBean とは、Javaで作成されたオブジェクト指向プログラミングにおけるコンポーネントの仕様であり、特定の規則に従って設計されたクラスのことを指します。これらの規則により、JavaBeanは他のアプリケーションやフレームワークと容易に連携し、再利用可能なコンポーネントとして機能します。