シングルトンを実装する方法としては、privateコンストラクタを使用するか、enumを使用するというものです。
記載内容
enumによるシングルトン
特に理由が無ければ、シングルトンを実装したい場合、単一要素のenum型を使用すれば良い。
ただし、何らかの親クラスを拡張したい場合は、enumは使えない。
(インタフェースを実装することはできる)
privateコンストラクタによるシングルトン
enum型で実装しない場合はこちらを使用することになる。
この場合、方法は大きく二つに分かれる
- public static finalフィールドにインスタンスを保持する
- ファクトリメソッドにより単一インスタンスを返す
前者の方がシンプルであり、シングルトンであることが明示的である。
後者のメリットは、シングルトンかどうかを後から変更できることと、
ファクトリメソッドをSuuplier>として使えること。
この2つのメリットが重要でなければフィールドで保持すればよい。
シングルトンクラスをSerializableにしたい場合、privateコンストラクタによる方法では、
readResolveの実装が必要いなる。
考察
そもそも、シングルトンパターンが良いか、という問題がありますが、
シングルトンを採用するのであれば、この項目の記載に従うのが良いです。
あまり見かけないかもしれないが、特に理由が無ければ、enum型で実装してしまうのが良いと思われます。
ファクトリメソッドのメリットとして、Supplier>での使用について記載されていますが、
フィールドで保持する場合でも(enumの要素でも)、
() -> Singleton.INSTANCE
とすれば良いだけなので、ファクトリメソッドのメリットとしてはあまり強くないと思います。
どちらかと言えば、ファクトリメソッド化することで、遅延初期化等、実装の詳細を隠ぺいできることが大きいです。
(遅延初期化も乱用するべきではないと思いますが)