Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hallo,

ich habe mir ein Enum aufgebaut, ungefähr so:

public enum Eingabe

{

  USER      ( new User() ),

  PASSWD ( new Password());


[I]//Konstruktor[/I]

  private AbstractEingabe clazz; 

  private Eingabe(AbstractEingabe abstract)

  {

    this.clazz = abstract

  }

}
Die Klassen, die AbstractEingabe implementieren, verwende ich in einem a'la-Strategy-Muster, d.h. situationsabhängig setze ich den Kontext meines Programmes auf User / Password und es werden entsprechende Versionen meiner Methoden ausgeführt. Meine Frage ist wahrscheinlich lächerlich aber: wie kann ich sicherstellen, dass im Laufe des Programms nur eine einzige Instanz jeder der Klassen existiert? Ginge das so?
public enum Eingabe{

  USER(getUser()),

  PASSWORD(getPassword();


 [I] //Konstruktor[/I] ...


  private static Password password = new Password();

  private static AbstractParameter getPassword()

  {

    return password;

  }

  ...(User analog)

Ich bin mir nicht sicher... und wäre für jede Hilfe dankbar :confused:

Geschrieben

Wenn eine Klasse nur einmal existieren soll dann kann man den Konstruktor "private" setzen und sich die Instanz dann über eine statische methode holen.

z.B.:


public class Single{

    private static Single instance;


    private Single(){


    }


    public static Single getInstance(){

        if(instance == null){

            instance = new Single();

        }


        return instance;

    }

}

Geschrieben
Wenn eine Klasse nur einmal existieren soll dann kann man den Konstruktor "private" setzen und sich die Instanz dann über eine statische methode holen.

z.B.:


public class Single{

    private static Single instance;


    private Single(){


    }


    public static Single getInstance(){

        if(instance == null){

            instance = new Single();

        }


        return instance;

    }

}

Nur als Ergänzung:

Das obige nennt man "Singleton" und ist ein Design Pattern.

Geschrieben

  1. Singletons sollten final sein.
  2. Bei Lazy Creation sollte man Threadsicherheit beachten (synchronized).
  3. Sollte man abwägen ob eine Eager Creation nicht sinnvoller ist.
  4. Versuche ich zumindest weitestgehend auf Singletons zu verzichten. Gibt fast immer andere Möglichkeiten das zu implementieren.

Geschrieben
  1. Singletons sollten final sein.
  2. Bei Lazy Creation sollte man Threadsicherheit beachten (synchronized).
  3. Sollte man abwägen ob eine Eager Creation nicht sinnvoller ist.
  4. Versuche ich zumindest weitestgehend auf Singletons zu verzichten. Gibt fast immer andere Möglichkeiten das zu implementieren.

Gibt es eine Vorschrift (CodeConventions o.ä.), dass Singletons final sein sollen?

Threadsicherheit spielt nur eine Rolle wenn man überhaupt mit Threads arbeitet.

Synchronized sollte mit bedacht gewählt werden, da sich dies erheblich auf die Performance ausübt (Ganz abgesehen von der lesbarkeit des Code ["Warum verwendet er hier synchronized? Wo greifen hier andere Threads zu?])

Singletons haben durchaus ihre Berechtigung. Sonst hätten sie nicht den weg in die Design-Patterns gefunden. Wie oft man sie einsetzt, muss man wohl von Fall zu Fall abwägen.

Geschrieben
Gibt es eine Vorschrift (CodeConventions o.ä.), dass Singletons final sein sollen?

Ich habe jetzt das Pattern nicht in der Originaldefinition im Kopf, vermute aber, dass sich das "final" darauf bezieht, dass man ansonsten ohne

Probleme eine Subklasse Deines Singletons definieren kann und dieser dann einen öffentlichen Konstruktor spendiert. Damit wäre diese Subklasse aber kein Singleton mehr. Durch die Vererbung wird aber eine "ist ein" Beziehung definiert und damit hast Du einen semantischen Fehler und potenzielle Probleme.

Peter

Geschrieben

Zum Thema final oder nicht:

Ich denke es ist eher eine Sache, dass der Compiler Optimierungen durchführen kann.

Eine Subklasse abzuleiten und einen öffentlichen Konstruktor einzuführen, während es einen privaten Konstruktor(ohne Parameter) in der Basisklasse gibt, sollte nicht funktionieren.

Sollte es dennoch jemand schaffen, bin ich an einem Beispiel interessiert :).

Geschrieben

Ich habe heute morgen aus dem Bauch heraus auch erst mal gesagt, dass das nicht geht. Aber das Beispiel dazu ist trivial und kompiliert:


public class Foo {

  private Foo() {}

}


public class Bar extends Foo {

  public Bar() {}

}

Und selbst, wenn das nicht gegangen wäre, dann könnte ich den Konstruktor ja ohne Probleme überladen und den Kontruktor öffentlich machen. Ich glaube, die Sichtbarkeit verringern innerhalb einer Subklasse geht nicht, aber Sichtbarkeit erhöhen ist möglich.

Und deshalb wird es schon dieser Grund sein, der für ein final spricht. Die generelle Empfehlung, final dort zu verwenden, wo es möglich ist, ist ja ein anderes Thema.

Peter

Geschrieben

Sorry, jetzt bin ich verwirrt. Auch auf die Gefahr hin vom eigentlichen Thema abzuweichen, möchte ich noch einmal darauf eingehen.

Ich habe die beiden Klassen unter 1.5 kompiliert und erhalte bei dem Kompilieren beim Konstruktor von Bar() eine Fehlermeldung:

"Implicit super constructor Foo() is not visible. Must explicitly invoke another constructor"

Auch das Überladen habe ich versucht, aber bekomme dabei auch eine Fehlermeldung.


public class Bar extends Foo {


	public Bar() {}


	public Bar(String text) {

		this();

	}

}

Muss ich etwas an den Compile-Einstellungen ändern?

Vielen Dank.

Geschrieben

Servus,

das ist ja lustig. Ich habe mein Beispielprojekt von gestern noch mal in Eclipse geöffnet und heute kompiliert es mit der selben Fehlermeldung wie bei Dir nicht mehr. Gestern hat mir Eclipse keinen Fehler gezeigt.

An den benötigten Aufruf eines Super-Konstruktors habe ich natürlich nicht gedacht. Das stimmt, dass dann bei einer Superklasse, die ausschließlich private Konstruktoren definiert, keine Subklasse mit einem Konstruktor irgendeiner Art definiert werden kann. Das ist ja dann eigentlich auch so eine Art final, oder? ;)

Sorry für die Verwirrung - ich gelobe das Kompilieren ausschließlich mit der Kommandozeile für zukünftige Showcases. :)

Peter

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...