Angularにおけるサービス vs. ファクトリー

EDIT 2016. なお、2015年の投稿の再掲載であるこの投稿は、Angular 1に関するものです。 私はもうフロントエンドをやっていないので、この投稿が Angular 2 に関連しているという保証はありません ;).

私の Hack Reactor クラスメートの 1 人と私は最近、Moxe Health の高血圧治療計算機を構築しました。この会社は、Moxe のネットワーク内の任意の病院の電子医療記録に、どの開発者もアクセスできるデータベース統合システムおよび API を構築中の刺激的な Rock Health の会社です。 Moxeとそのプロジェクトについては、別の記事で紹介したいと思います。 私たちは、データバインディングやその他の素晴らしい機能を備えた強力なフロントエンドフレームワークであるAngularで、アプリのフロントエンドを構築しました。 混乱したことの一つは、サービスとファクトリーをいつ使うかということでした。 Stack Overflow に、この 2 つの違いに関する良いスレッドがありますが、まだ Javascript の知識を固めていない開発者に役立つと思われるいくつかのアナロジーが省かれています。

この投稿では、2 つの違いを学びます。

TLDR – ファクトリーとサービスには、メソッドとプロパティをインスタンス化してカプセル化するという点において、ほとんど同じ機能があり、関数的インスタンス化と疑似クラス化パターンが同様の能力を持つように、同じような機能があります。 Angularのコミュニティでは、どちらを使うか好みはありません。 ファクトリーレシピとサービスレシピはプロバイダーレシピの上にある構文上の砂糖に過ぎません。 つまり、「ファクトリーとサービスのどちらを使うべきか」ではなく、「関数型インスタンス化と擬似クラスタリングインスタンス化のどちらを使うべきか」ということを自問自答すべきなのです。「

このハイレベルな理解以外に最も重要な違いは、インスタンス化パターンの違いの結果として、ファクトリーはプリミティブと関数を返すことができますが、サービスはそうではないということです。 コードのほとんどを提供してくれた Epokk に謝意を表します。 私は、Angular に慣れていない開発者がここでの違いを掘り下げるのに役立つように、いくつかの変更を加えました。 JSFiddleを初めて使う方は、javascript、html、cssファイル間のインタラクションを簡単にテストすることができるツールです。

この例のサービスとファクトリーの両方は、文字列 “Hello World!” を返すという同じ機能を備えています。

サービスはオブジェクトをインスタンス化し、そのオブジェクトの “sayHello” プロパティに “Hello World!” を返す関数を代入します。sayHello().

ファクトリーは “Hello World!”を返す関数を返します:

return function() { return "Hello, World!" };

その関数はコントローラで呼び出されます: helloWorldFromFactory()です。 ファクトリーの参照が、サービスの例のように値が関数であるオブジェクトのプロパティではなく、 返された関数を指していることに注意してください。 なぜなら、サービスは空のオブジェクトをインスタンス化しなければならず、 そのオブジェクトはサービス関数内で ‘this’ を参照するからです。 サービスは常にオブジェクトを返します。

ここで、ファクトリーの混乱しやすい部分を説明します。

return { sayHello: function() { return "Hello, World!" } };

このメソッドは、サービスの sayHello 関数を呼び出すのと同じように、コントローラで呼び出すことができます。

後者のファクトリー形式は、ファクトリー内に複数のメソッドを持つ場合に便利です。

return { sayHello: function() { return "Hello, World!" }, sayGoodbye: function() { return "Goodbye, World!" } };

ここでも重要なのは、Angular でコーディングしているという事実にとらわれず、サービスとファクトリーの違いは、ほとんどの場合、疑似クラス化および関数化インスタンスの違いと同じであることを覚えておいてください。

Source code for the curious

Here is the Angular source code, demonstrate that services & factories is layered on top on the more general providers feature:

//provider function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name); } return providerCache = provider_; } //factory function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); } //service function service(name, constructor) { return factory(name, ); }

The both service and factory create singletons.This is the difference of the service and factory can’t know the difference of the difference of the singleletson. ここでは、基本的な機能的継承と擬似的なクラス的継承のパターンを示しています。 ファクトリーは factoryFn が返すものをすべて返します。

サービスは擬似クラスのインスタンスを返します。 擬似クラスのコンストラクタは、Angularのサービスビルダーservice()に渡されます。 コンストラクタがサービスビルダーサービスに渡される(return $injector.instantiate(constructor) )という事実は混乱を招くかもしれませんが、return new constructor() とだけ考えてください。

Leave a Reply