こちらを読むと
- Java オブジェクト指向のデザインパターンであるstaticファクトリメソッドの利点、使用例を知ることができます
- 記事を読む所要時間は10分です。
結論
- staticファクトリメソッドは、コンストラクタで不可能なことをしたいときに使うべき!
いきなり結論です。
以降、詳細を解説していきます。
staticファクトリメソッドとは
- そのクラスのオブジェクトを生成できる、staticメソッド
- コンストラクタの代わりに使える
staticファクトリメソッドの例
Java BooleanクラスのvalueOfメソッドを例にとります
1 2 3 |
public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } |
staticファクトリメソッドの利点
- 名前をつけることができる
- オブジェクトを再利用可能
- サブクラスのオブジェクトを返せる
- エラー処理が可能
以下、解説していきます。
1.名前をつけることができる
コンストラクタの名前はクラス名と同じにしなければならないので、「この場合はこういうオブジェクトを返すことを表現したい!」と思っていても、コンストラクタでは表現できません。
この問題の解決にstaticファクトリメソッドが使えます。
例えばBigIntegerのprobablePrimeというstaticファクトリメソッドは、その名の通り、「おそらく素数」の値を生成します。この内容は、コンストラクタでは表現できません。
2.オブジェクトを再利用可能
クラスの設計次第ですが、生成したオブジェクトをクラス内部で保持しておき、staticファクトリメソッドが呼び出されるたびに、保持しておいたオブジェクトを返すようにしておけば、オブジェクト生成のコストを削減できます。
例えば以下のような実装になります。
1 2 3 4 5 6 7 8 9 10 |
class Example { private static Example exam; public static Example makeExample() { if (exam == null) { exam = new Example(); } return exam; } } |
makeExampleで、内部に保持しているexamオブジェクトを返すようにしています。ここでは最初に呼ばれたとき(まだnullのとき)だけ生成するようにしています。
3.サブクラスのオブジェクトを返せる
コンストラクタで返せるオブジェクトは、そのクラスそのもののオブジェクトしかあり得ませんよね。
staticファクトリメソッドを使うとどうでしょうか。
内部では生成するオブジェクトを自由に選べるので、メソッドの戻り値の型に一致してさえいれば、好きなオブジェクトを生成して返すことができます。
すなわち、そのクラスのサブクラスを生成して返すことができるわけです。
これにより、引数の内容で返すオブジェクトを切り替える、ファクトリパターンのようなことが可能になります。
4.エラー処理が可能
コンストラクタの内部でエラーが発生してしまった場合、どうなるでしょうか。
コンストラクタ内部では例外のキャッチやエラー処理ができないため、もし例外が発生すると、オブジェクト生成失敗してそれっきり、となってしまいます。
staticファクトリメソッドでは例外のキャッチやエラー処理を行うことができるので、例外をスローしたり、戻り値で異常値を返したりすることができるのです。
オブジェクト生成時に複雑な処理をしているクラスでは、有効な施策だと思います。
まとめ
- オブジェクト指向のデザインパターンであるstaticファクトリメソッドの利点、使用例を知ることができました
- 結論としては、staticファクトリメソッドは、コンストラクタで不可能なことをしたいときに使うべき!です
Reference
Effective Java 第3版
https://www.amazon.co.jp/dp/4621303252