Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

AngularのServiceとFactoryの使い分け(ほぼ)決定版

(この記事はQiitaで僕が書いたものを移行した記事です。記事中のコメントはQiitaの該当記事を参照ください)

ようやくわかったのでまとめておきます。決定版と言って差し支えないはずです。これ読めば 絶対に ServiceとFactoryの違いがわかります。これでもう迷わずに使い分けられるはずです。

ServiceとFactoryの関係

そもそもFactoryもServiceもProviderの一種です。そして、ServiceをFactoryに書き直し可能です。 angular.module(app).service(name, f)angular.module(app).factory(function(){return new f();}); と書き直せます。

が、もちろんこの書き直しはすべきではありません。これはServiceであることを隠蔽してしまっています。暗黒ですね。

ServiceとFactoryのそれぞれ使うべき場面

私は今まで漫然とFactoryを多用してました。しかし、おそらく自分がFactoryにしてたものは全てServiceとするべきものでした。「Serviceは全てFactoryで置き換えられる症候群」に罹ってる人も意外といるのではないでしょうか?

Serviceは、 あるデータを持ち、それに対して操作をする必要がある場合 に使います。

Factoryは 単にデータを保持する時(変更は加えられません)、関数群、ユーティリティとして使う時 に使います。

そもそも、Factoryは関数を受け取り関数を実行しその返り値を返す言い換えると プリミティブ値を返す わけです。プリミティブ値であるので、あくまで自身に操作を加えられるオブジェクトなどを使う場面では相応しくありません。そういう時はServiceです。

以前僕はカレンダーアプリを作ってました。その時、Factoryでカレンダーのモデルを作ってました。もちろんカレンダーなので何年何月のカレンダーかといった情報を持ち、変更可能な状態でした。今までの話でわかると思いますがこれ完全にServiceでするべきです。暗黒ですね。

ここでオブジェクト指向

突然ですがオブジェクト指向、理解できてますか? 私は理解できてませんでした。そしてこれが理解できる一言に出会い、色々なことを一度に理解しました。それは、 オブジェクト指向ではデータとその関連するメソッドをまとめてオブジェクトとする」 というものです。

このオブジェクト指向の理念に則っているのはServiceの方です。Serviceで生成されるのはnewでインスタンス化されたオブジェクトだからです。

上でも書きましたがもちろんFactoryでも同じことが出来ます。しかし、これは本来の用途とは外れます。Factoryは関数群、もしくは単にハッシュであるべきなのです。 データを持ち、操作できる構造なのにFactoryとなっているなら迷うことなく今すぐServiceに変えましょう 。まだ間に合います。

終わりに

何か指摘とかあったらコメントしてください。