私と一緒にここにいてください。私はそのような他の答えがあることを知っています。 AngularJS:サービスvsプロバイダvsファクトリ
しかし、いつでも工場でサービスを利用するのかわかりません。
私が言うことができるものからファクトリは一般的に複数のコントローラによって呼び出されることができる「一般的な」機能を作成するために使用されます: 一般的なコントローラ機能の作成
Angularドキュメントはファクトリよりサービスよりも好むようです。彼らは彼らが工場を使うとき「サービス」さえ参照します。 http://docs.angularjs.org/guide/dev_guide.services.creating_services
では、いつサービスを利用するのでしょうか?
サービスを利用した場合にのみ可能またはそれ以上に簡単なことがありますか。
舞台裏で何か違うことはありますか?パフォーマンス/メモリの違い
これが一例です。宣言の方法を除けば、それらは同一のように見えます、そして、なぜ私が一方と他方をやるのか私にはわかりません。 http://jsfiddle.net/uEpkE/
更新:Thomasの答えから、サービスは単純なロジック用で、ファクトリはプライベートメソッドを使ったもっと複雑なロジック用のファクトリであると思われるので、以下のフィドルコードを更新したようです。プライベート機能をサポートすることができますか?
myApp.factory('fooFactory', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo; }
return {
setFoobar: function(foo){
addHi(foo);
},
getFoobar:function(){
return fooVar;
}
};
});
myApp.service('fooService', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo;}
this.setFoobar = function(foo){
addHi(foo);
}
this.getFoobar = function(){
return fooVar;
}
});
function MyCtrl($scope, fooService, fooFactory) {
fooFactory.setFoobar("fooFactory");
fooService.setFoobar("fooService");
//foobars = "Hi fooFactory, Hi fooService"
$scope.foobars = [
fooFactory.getFoobar(),
fooService.getFoobar()
];
}
あなたはここで違うものを手に入れました:
最初:
this
"キーワード)を取得します。ref:angular.serviceとangular.factory
秒:
AngularJSのすべてのプロバイダ(値、定数、サービス、工場)はシングルトンです。
3番目:
どちらか(サービスまたはファクトリ)を使用することはコードスタイルについてです。しかし、Angular JSの 一般的な方法 は、 factory を使用することです。
どうして ?
なぜなら "ファクトリメソッドはオブジェクトをAngularJS依存性注入システムに入れる最も一般的な方法です。非常に柔軟で洗練された作成ロジックを含めることができます。ファクトリは通常の関数なので"private"変数をシミュレートするための新しい字句スコープの作成。これは、特定のサービスの実装の詳細を隠すことができるので非常に便利です。 "
(ref: http://www.Amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821 ).
Service:注入された関数参照に単に()
を追加することで呼び出すのに便利なユーティリティ関数を共有するのに役立ちます。 injectedArg.call(this)
などで実行することもできます。
Factory:インスタンスを作成するために新たに追加されることができる「クラス」関数を返すのに役立ちます。
そのため、 サービスに複雑なロジック がある場合はファクトリを使用し、 この複雑さを公開したくない場合は を使用してください。
他の場合では もしあなたがサービスのインスタンスを返したいならば単にservice を使ってください。
しかし、時間の経過とともに80%のケースでファクトリを使用することになるでしょう。
詳細については、 http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/
更新:
ここに優秀な投稿: http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html
msgstr "" "あなたの関数 を通常の関数 のように呼び出すには、factoryを使います。関数をnew演算子でインスタンス化するにはserviceを使います違いがわからない場合は、factoryを使ってください。」
更新:
AngularJSチームは自分の仕事をして説明をします: http://docs.angularjs.org/guide/providers
そしてこのページから:
「ファクトリとサービスは最も一般的に使用されるレシピです。それらの唯一の違いは、サービスレシピはカスタムタイプのオブジェクトに対してうまく機能するのに対し、ファクトリはJavaScriptプリミティブと関数を生成できるということです。」
allernhwkim もともとこの質問に 自分のブログ にリンクして 回答 を投稿しましたが、モデレータは削除しましたそれ。これは私が見つけた唯一の記事で、サービス、プロバイダー、ファクトリーで同じことをする方法を教えているのではなく、プロバイダーではできないこと、ファクトリーではできないこと、そしてサービスではできない工場.
彼のブログから直接:
app.service('CarService', function() {
this.dealer="Bad";
this.numCylinder = 4;
});
app.factory('CarFactory', function() {
return function(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
};
});
app.provider('CarProvider', function() {
this.dealerName = 'Bad';
this.$get = function() {
return function(numCylinder) {
this.numCylinder = numCylinder;
this.dealer = this.dealerName;
}
};
this.setDealerName = function(str) {
this.dealerName = str;
}
});
これは、CarServiceが常に4気筒の車を生産する方法を示しています。個々の車に変更することはできません。 CarFactoryが関数を返すのに対して、あなたはあなたのコントローラでnew CarFactory
をすることができます、その車に特有の多数のシリンダーを渡すこと。 CarServiceは関数ではなくオブジェクトなので、new CarService
を実行することはできません。
工場はこのようには機能しません。
app.factory('CarFactory', function(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
});
そして、インスタンス化するための関数を自動的に返します。それができないからです(プロトタイプなどに追加する)。
app.factory('CarFactory', function() {
function Car(numCylinder) {
this.dealer="Bad";
this.numCylinder = numCylinder
};
Car.prototype.breakCylinder = function() {
this.numCylinder -= 1;
};
return Car;
});
文字通り自動車を製造する工場であることをご覧ください。
彼のブログの結論はかなり良いです。
結論として、
--------------------------------------------------- | Provider| Singleton| Instantiable | Configurable| --------------------------------------------------- | Factory | Yes | Yes | No | --------------------------------------------------- | Service | Yes | No | No | --------------------------------------------------- | Provider| Yes | Yes | Yes | ---------------------------------------------------
Hashなどの単純なオブジェクトが必要な場合は、Serviceを使用します。{foo; 1、bar:2}コーディングは簡単ですが、インスタンス化することはできません。
New Customer()、new Comment()など、オブジェクトをインスタンス化する必要があるときはFactoryを使います。
設定が必要な場合はプロバイダを使用してください。すなわち、テストURL、QA URL、製造URL。
あなたがファクトリでオブジェクトを返しているだけであるとわかったなら、おそらくserviceを使うべきです。
これをしないでください。
app.factory('CarFactory', function() {
return {
numCylinder: 4
};
});
代わりにserviceを使ってください。
app.service('CarService', function() {
this.numCylinder = 4;
});
これらすべてのプロバイダの概念は、最初に登場したものよりもはるかに単純です。あなたがプロバイダあなたを詳細に分析して、異なる部分を引き出すなら、それは非常に明確になります。
簡単に言えば、これらのプロバイダのそれぞれが、provider
> factory
> value
/constant
/service
の順に、もう一方のプロバイダを特殊化したものです。
プロバイダができる限り長くあなたができる限りプロバイダを使用することができます。その結果、より少ないコードを書くことになります。それがあなたが望んでいることを達成しないなら、あなたはチェーンを上がることができます、そしてあなたはただもっと多くのコードを書く必要があるでしょう。
この画像は、私が何を意味するのかを示しています。この画像では、プロバイダのどの部分をファクトリ、値などの作成に使用できるかを強調表示した部分とともに、プロバイダのコードが表示されます。
私が行ってから画像を得たブログ記事からのより多くの詳細と例については: http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider -and-factory-in-angularjs /
ファクトリとサービスの両方が、プロバイダによって設定され、コントローラと実行ブロックに注入されることができるシングルトンオブジェクトをもたらします。注入先の観点からは、オブジェクトが工場から来たのかサービスから来たのかには全く違いはありません。
それでは、いつ工場を利用し、いつサービスを利用するのでしょうか。それはあなたのコーディングの好みに煮詰まり、そして他には何もない。あなたがモジュラーJSパターンを好めばそれから工場に行きなさい。あなたがコンストラクタ関数( "クラス")スタイルを好めばそれからサービスのために行きなさい。どちらのスタイルもプライベートメンバーをサポートしています。
このサービスの利点は、OOPの観点から直観的にわかりやすいことです。「クラス」を作成し、プロバイダと連携して、モジュール間で同じコードを再利用してインスタンス化されたオブジェクトは、コンフィグブロック内のコンストラクタに異なるパラメータを渡すことによって単純になります。
たとえ彼らがすべてのサービスや工場がシングルトンであると言ったとしても、私はそれに100パーセント賛成しません。私は工場はシングルトンではないと言うでしょう、そしてこれが私の答えのポイントです。私は本当にすべてのコンポーネントを定義する名前(Service/Factory)について考えます。
Aファクトリはシングルトンではないので、注入するときに必要なだけ作成できます。つまり、オブジェクトのファクトリのように機能します。あなたはあなたのドメインのエンティティのファクトリを作成し、あなたのモデルのオブジェクトのようになることができるこのオブジェクトでより快適に作業することができます。複数のオブジェクトを取得すると、それらをこのオブジェクトにマップでき、DDBBとAngularJsモデルの間の別のレイヤーのように機能できます。オブジェクトにメソッドを追加して、AngularJsアプリケーションをもう少しオブジェクトに向けることができます。
一方、サービスはシングルトンなので、作成できるのは1種類だけで、作成できないかもしれませんが、コントローラにインジェクトするときに1つのインスタンスしかありません。そのため、サービスはコントローラに対してより一般的なサービス(呼び出しの休止、機能など)を提供します。
概念的には、サービスはサービスを提供するように考えることができ、ファクトリーはクラスの複数のインスタンス(オブジェクト)を作成することができます
ファクトリーがサービスと比較してできない、またはそれ以上に優れているものは何もありません。そしてその逆です。工場はもっと人気があるようです。その理由は、プライベート/パブリックメンバーを処理するのに便利だからです。この点でサービスはもっと不器用でしょう。サービスをコーディングするときは、「this」キーワードを使ってオブジェクトメンバーを公開する傾向があり、それらの公開メンバーがプライベートメソッド(つまり内部関数)から見えないことが突然見つかるかもしれません。
var Service = function(){
//public
this.age = 13;
//private
function getAge(){
return this.age; //private does not see public
}
console.log("age: " + getAge());
};
var s = new Service(); //prints 'age: undefined'
Angularは「new」キーワードを使用してサービスを作成します。そのため、コントローラに渡されるインスタンスAngularにも同じ欠点があります。もちろん、これを使うことで問題を克服することができます。
var Service = function(){
var that = this;
//public
this.age = 13;
//private
function getAge(){
return that.age;
}
console.log("age: " + getAge());
};
var s = new Service();// prints 'age: 13'
しかし、大きなService定数を使用すると、このことによってコードの読みやすさが低下します。さらに、サービスのプロトタイプでは非公開のメンバーは表示されません。公開されているメンバーだけが利用できます。
var Service = function(){
var name = "George";
};
Service.prototype.getName = function(){
return this.name; //will not see a private member
};
var s = new Service();
console.log("name: " + s.getName());//prints 'name: undefined'
まとめると、Factoryを使用する方が便利です。工場にはこれらの欠点はありません。デフォルトで使用することをお勧めします。
サービス
構文:module.service( 'serviceName'、function); 結果:注入可能な引数としてserviceNameを宣言すると、module.serviceに渡される実際の関数参照が提供されます。
使用法:挿入された関数参照に単純に()を追加することで呼び出すのに便利なユーティリティ関数を共有するのに役立ちます。 injectArg.call(this)などで実行することもできます。
工場
構文:module.factory( 'factoryName'、function);
結果:factoryNameを注入可能な引数として宣言すると、module.factoryに渡された関数参照を呼び出すことによって返される値が提供されます。
使用法:インスタンスを作成するために新しく追加できる 'class'関数を返すのに便利です。
プロバイダ
構文:module.provider( 'providerName'、function);
結果:注入可能引数としてproviderNameを宣言すると、moduleに渡された関数参照の$ getメソッドを呼び出すことによって返される値が提供されます。プロバイダ.
使用法:インスタンスを作成するために新しく追加することができますが、注入される前に何らかの設定が必要な 'class'関数を返すのに便利です。 。プロジェクト間で再利用可能なクラスにはおそらく便利でしょうか。これでもやや濁っています。
FactoryとServiceが最も一般的に使用されている方法です。唯一の違いは、Serviceメソッドは継承階層を必要とするオブジェクトに適しているのに対し、FactoryはJavaScriptのプリミティブと関数を生成できるという点です。
Provider関数はコアメソッドであり、他のすべてのものは単なる構文糖です。グローバル構成を必要とする再利用可能なコードを構築している場合にのみ必要です。
サービスを作成するには、Value、Factory、Service、Provider、Constantの5つの方法があります。あなたはここでこれについてより多くを学ぶことができます 角度サービス 、この記事は実用的なデモ例でこれらすべての方法を説明します。
。
両方ともあなたが望む方法を使うことができます:create objectまたはj両方から関数にアクセスしたい
サービスから新しいオブジェクトを作成することができます
app.service('carservice', function() {
this.model = function(){
this.name = Math.random(22222);
this.price = 1000;
this.colour = 'green';
this.manufacturer = 'bmw';
}
});
.controller('carcontroller', function ($scope,carservice) {
$scope = new carservice.model();
})
注意 :
ファクトリから新しいオブジェクトを作成することができます
app.factory('carfactory', function() {
var model = function(){
this.name = Math.random(22222);
this.price = 1000;
this.colour = 'green';
this.manufacturer = 'bmw';
}
return model;
});
.controller('carcontroller', function ($scope,carfactory) {
$scope = new carfactory();
})
注意 :
単純な関数にアクセスするためのサービスを作成する
app.service('carservice', function () {
this.createCar = function () {
console.log('createCar');
};
this.deleteCar = function () {
console.log('deleteCar');
};
});
.controller('MyService', function ($scope,carservice) {
carservice.createCar()
})
単純な関数にアクセスするためのファクトリを作成する
app.factory('carfactory', function () {
var obj = {}
obj.createCar = function () {
console.log('createCar');
};
obj.deleteCar = function () {
console.log('deleteCar');
};
});
.controller('MyService', function ($scope,carfactory) {
carfactory.createCar()
})
結論: