他のクラスをシングルトンクラスから派生させるにはどうすればよいですか?
質問
これが重複しているか、あまりにも初歩的な場合は申し訳ありませんが、サブクラス化できるシングルトンクラスを作成するにはどうすればよいですか?
解決
Steve Yeggeには、この引用でサブクラス化について言及しているシングルトンに関する面白い記事があります。 :
次に、サブクラス化があります。 サブクラス化することはほとんど不可能です シングルトン、そしてあなたがそれを管理するなら、 使用してはいけません そもそもシングルトン。君は 行きたくない偶数。しました 私はあえて語らない道を歩きました。 できないふりをして 驚くほどの量を節約できます 痛みの。
他のヒント
通常、あなたはどんな意味でもできない。これは、Singletonクラスを使用しないもう1つの理由です。
実際、それは可能だとは思わない。
コンストラクタを private
として宣言することにより、クラスをシングルトンにします。しかし、その後、シングルトンクラスのサブクラスを宣言しようとすると、サブクラスコンストラクターはスーパークラスのコンストラクターを参照できなくなります。そのため、それらはコンパイルされません。例:
public class A () {
private A() { }
}
public class B () {
private B() { }
}
Sun JDK 1.6とEclipse Ganymedeコンパイラーはどちらも、コンストラクターBでコンパイルエラーを発生させます。これにより、Aの引数なしのコンストラクターが表示されなくなります。
private
コンストラクターの可視性を高めることはできますが、その場合、誰かがそのインスタンスを複数作成するのを防ぐことはできません(良識は別として)。つまり、実際にはシングルトンクラスではなくなりました。
編集:コーシャの代替案は、共通にするメソッド/メンバーで1つ以上の抽象(非シングルトン)クラスのツリーを定義し、次に複数のシングルトンクラスをリーフクラスとして定義することだと思います適切な。しかし、それは別のシングルトンクラスをサブクラス化するものではありません。
シングルトンを次のように定義している場合:
public class Singleton {
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
private Singleton() {
}
}
その後、次の操作を実行できます。
public class NewSingleton extends Singleton {
}
ただし、プライベートメソッドを使用することはできないため、シングルトンを使用する場合は、 Singleton.getInstance();
を呼び出す必要があるため、拡張しても何も得られません。
しかし、それができない理由はありません。
今、Singletonクラスにさらに機能を追加したい場合、AspectJから型間アスペクトを使用し、Singletonが使用できる新しいメソッド/プロパティをSingletonに挿入するだけです。
シングルトンは、継承ではなくインスタンスを制限します。さて、既に指摘したように、継承の有用性を制限し、プライベートコンストラクターをパッケージ化または保護(シングルトンの単一性を減少させると主張するかもしれません)に緩和できますが、目的は何ですか?
他の人がすでに答えているように、シングルトンのサブクラス化の使用はわずかです。シングルトンのコンテキストで戦略パターンが必要な場合は、インターフェイスを定義し、シングルトンインスタンスでそのインターフェイスの実装に委任できます。これにより、問題が1層下に移動し、それを行う理由がより明確になります。
質問に答えるには;アプリケーションが使用する特定のサブクラスの選択が、たとえばシステムプロパティで定義されていると仮定すると、次のようなことができます。
public static synchronised Singleton getInstance() {
if (instance == null) {
String clsName = System.getProperties().getProperty("singleton.class");
if (className == null || 0 == clasName.length()) {
instance = new Singleton();
} else {
Class cls = Class.forName(clsName);
instance = (Singleton) cls.newInstance();
}
}
return instance;
}
免責事項:テストされていないコード、例外処理の追加など:-)
ところで、 getInstance()
メソッドが同期されていることを確認してください。