2009-05-15 4 views
11

Ich habe einige Klassen, die als Singletons verwendet werden. Sie teilen einige grundlegende Funktionen und erweitern den gleichen Vorgänger aus einer Bibliothek, die normalerweise nicht als Singleton verwendet wird.Wie kann ich einen Singleton haben, der von einem abstrakten Basistyp in Java abgeleitet ist?

Wenn ich die allgemeine Funktionalität in eine Basisklasse, die vom gemeinsamen Vorfahren erbt, stelle, bekomme ich eine Klasse, die keinen Sinn zu instantiieren, also habe ich es abstrakt gemacht. Da die Klassen alle als Singletons verwendet werden, sollten sie alle eine init() - und eine getInstance() -Methode haben, die beide statisch sind. Alle Konstruktoren sind natürlich nicht öffentlich. Jetzt

, da static ist eine illegale Modifikator für abstrakte Methoden, die folgenden nicht funktioniert, obwohl dies genau sein würde, was ich will:

class Base extends LibraryClass { 
    protected Base() { 
     // ... constructor 
    } 

    // ... common methods 

    // ILLEGAL! 
    public static abstract void init(); 
    public static abstract <T extends Base>T getInstance(); 
} 

class A extends Base { 
    private static A _INSTANCE; 

    private A() { 
     super(); 
    } 

    public static void init() { 
     _INSTANCE = new A(); 
    } 

    public static A getInstance() { 
     return _INSTANCE; 
    } 
} 

Ich konnte nur die illegalen Linien in der Basis auslassen Klasse und damit fertig sein. Aber wie kann ich ausdrücken, dass jedes Kind der Basis diese Methoden haben muss?

Antwort

14

Dies ist in Java nicht möglich. Existenz von static Methoden können nicht durchgesetzt werden; weder durch abstract noch unter Verwendung einer interface.

Meine Lösung war es, IoC auf eine Art zu verwenden: Ich habe eine Fabrikklasse für Singletons erstellt. Es würde die Singletons in einer Karte speichern. Der Schlüssel wäre die Klasse. Auf diese Weise kann ich sagen:

A singleton = Factory.create (A.class); 

Der große Vorteil dieser Konstruktion: Ich kann ein Factory.replace() Verfahren schaffen, in dem Testfall die Singletons außer Kraft setzen kann.

+0

Warum brauchen wir Singleton, obwohl wir bereits über Static oder Final in Java verfügen? Was ist? der Major resign/cause, der uns zwingt, "Singleton" anstelle von "Static, Final" zu übernehmen? Obwohl Singleton zu erreichen, verwenden wir Static.Ich konnte dieses Rätsel nicht verstehen. Bitte geben Sie Ihre Kommentare ab. –

+0

statische final ist für Konstanten, die eifrig erstellt werden. Ein Singleton wird normalerweise faul erstellt (nur wenn es benötigt wird). Außerdem erlaubt das statische Final nicht, die "Konstante" durch ein Modell zu ersetzen. Daher machen sie Tests schwierig oder sogar unmöglich. –

+0

Siehe http://stackoverflow.com/questions/11831/singletons-good-design-or-a-crutch –

2

Sie können nicht ausdrücken, dass untergeordnete Klassen spezifische statische Methoden haben.

In der Tat sollte dies nicht notwendig sein, da die statischen Methoden nur direkt auf die untergeordneten Klassen (A.init() und A.getInstance() in Ihrem Beispiel) und nie durch einen Verweis auf die Basisklasse aufgerufen werden (dh statische Methoden nicht Unterstützung Polymorphismus).

1

Warum gehst du nicht den ganzen Weg und machen Sie Ihre Fabrik (in der Basisklasse) übergeben Sie einen Parameter, der angibt, welche Unterklasse Sie zurückgeben möchten. Es gibt viele Vorteile, dies zu tun, und wenige Nachteile.

Die Art und Weise, wie Sie dies versuchen, macht keinen großen Sinn, da statische Methoden nicht mit der Vererbung umgehen, wie dies bei normalen Methoden der Fall ist.

3

Eine gängige Methode zum Hinzufügen von Singleton-Semantik zu einer Klasse, für die es ungünstig ist, die Semantik korrekt hinzuzufügen, besteht darin, die Singleton-Funktionalität in einer Wrapper-Klasse zu implementieren. Zum Beispiel:

public class UsefulThing { 

} 

public final class SingletonOfUsefulThing { 
    private static UsefulThing instance; 

    private SingletonOfUsefulThing() {} 

    public UsefulThing getInstance() { 
     if (instance == null) { 
      instance = new UsefulThing(); 
     } 

     return instance; 
    } 
} 

Auf diese Weise können Sie einige der primären Singleton Vorteile einer Klasse ohne einige der Folgen geben, dass die Singleton Semantik in der Klasse Umsetzung zwingt Sie direkt zu behandeln und ermöglicht einen gewissen Spielraum für die sich wandelnde bestimmter Typ der Klasse, die Sie als Singleton bereitstellen (z. B. mithilfe einer Factory zum Erstellen der Instanz.

+0

Ich denke, Ihre 'getInstance()' Methode sollte auch 'static' sein. – Koen

Verwandte Themen