ユーティリティ関数でいっぱいのクラスがあります。インスタンスをインスタンス化しても意味はありませんが、そのメソッドを呼び出したいと思います。これに対処する最良の方法は何ですか?静的クラス?抽象?
Finalとしてマークされたクラスのプライベートコンストラクターおよび静的メソッド。
素晴らしい本によると "Effective Java" :
項目4:プライベートコンストラクターでインスタンス化不可能性を強制する
-クラスを抽象化することでインスタンス化不可能性を強制しようとしても機能しません。
-デフォルトのコンストラクターは、クラスに明示的なコンストラクターが含まれていない場合にのみ生成されるため、プライベートコンストラクターを含めることでクラスをインスタンス化できないようにすることができます:
// Noninstantiable utility class
public class UtilityClass
{
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
}
明示的なコンストラクタはプライベートであるため、クラスの外部からはアクセスできません。 AssertionErrorは厳密に必須ではありませんが、コンストラクターがクラス内から誤って呼び出された場合に備えて保険を提供します。いかなる状況でもクラスがインスタンス化されないことを保証します。このイディオムはやや直感に反します。コンストラクターは明示的に提供されるため、呼び出せません。したがって、上記のようにコメントを含めるのが賢明です。
副作用として、このイディオムはクラスがサブクラス化されることも防ぎます。すべてのコンストラクターは、明示的または暗黙的にスーパークラスコンストラクターを呼び出す必要があり、サブクラスにはアクセス可能なスーパークラスコンストラクターがありません。
Java.lang.Math に似たユーティリティクラスがあるように聞こえます。
アプローチには、プライベートコンストラクターと静的メソッドを持つfinalクラスがあります。
しかし、これがテスト容易性のために何をするかに注意してください、私はこの記事を読むことをお勧めします
静的メソッドはテスト容易性の低下
上流へ泳ぐためだけに、静的メンバーとクラスはOOに参加しないため、悪意があります。いいえ、悪ではありませんが、真剣に、アクセスにはシングルトンパターンを持つ通常のクラスをお勧めします。このように、将来の動作をオーバーライドする必要がある場合、それは大した改造ではありません。 OOはあなたの友達です:-)
私の0.02ドル
「プライベートコンストラクター」引数についてコメントします。さあ、開発者はそんなに愚かではありません。しかし、彼らは怠け者です。オブジェクトを作成してから静的メソッドを呼び出しますか?起こらない.
クラスを悪用しないように時間をかけすぎないでください。あなたの同僚にいくらかの信仰を持っています。そして、あなたがそれをどのように保護しても、常にあなたのクラスを悪用する方法があります。誤用できない唯一のものは、まったく役に立たないものです。
クラスをstatic
として宣言しても意味がありません。メソッドをstatic
宣言し、Javaの Math クラスのように、通常どおりクラス名から呼び出します。
また、コンストラクターをプライベートにする必要はありませんが、そうすることをお勧めします。コンストラクターをプライベートとしてマークすると、他の人がクラスのインスタンスを作成し、それらのインスタンスから静的メソッドを呼び出すことができなくなります。 (これらの呼び出しはJavaでもまったく同じように機能し、誤解を招くだけでコードの可読性を損ないます。)