Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[LANG] Singleton einer abstrakten klasse ?

0 views
Skip to first unread message

bernd hohmann

unread,
Nov 12, 2002, 3:05:43 PM11/12/02
to
siehe betreff:

ich will mir mit einer statischen methode ein singleton meiner
abstrakten klasse abholen.

gibt es da strategien dafür ?

bernd

..
Boris Podolsky: James ?! Wie geht es dir, was machen die Ratten ?
James Moreland: Nun - zur Zeit sind es eher die Studenten, mit denen ich Experimentiere.
Kurt Gödel: Um Herrgottswillen, diese Labyrinthe müssen aber gross sein !

Andree Große

unread,
Nov 12, 2002, 2:21:02 PM11/12/02
to
bernd hohmann schrieb:

>
> siehe betreff:
>
> ich will mir mit einer statischen methode ein singleton meiner
> abstrakten klasse abholen.

private static MyClass instance;

public static MyClass getInstance () {
if (instance == null) {
instance = new MyClass();
}
return instance;
}

Meintest Du sowas?
A.G.

Sven Kuenzler

unread,
Nov 12, 2002, 2:41:18 PM11/12/02
to
Andree Große schrieb:

> bernd hohmann schrieb:
>
>>siehe betreff:
>>
>>ich will mir mit einer statischen methode ein singleton meiner
>>abstrakten klasse abholen.
>
>
> private static MyClass instance;
>
> public static MyClass getInstance () {
> if (instance == null) {
> instance = new MyClass();

Wobei letzteres bei einer abstrakten Klasse MyClass in die Binsen geht,
oder nicht?
Vermutlich müsste man etwas in der Art machen:

String clazz = System.getProperty("favourite.myclass.impl"); // osä.
instance=(MyClass)Class.forName(clazz).newInstance();

> }
> return instance;
> }

Sven

bernd hohmann

unread,
Nov 12, 2002, 3:50:25 PM11/12/02
to
On Tue, 12 Nov 2002 20:21:02 +0100, Andree Groáe wrote:

[...]

> Meintest Du sowas?

geht nicht weil "new MyClass()" beim kompilieren sagt "kann keine
instanz einer abstrakten klasse erstellen"

public abstract MyClass { .... }

oder kann man abstrakte methoden implementieren ohne dass die klasse
als abstrakt deklariert wird ?

konkret geht es darum (vielleicht hat jemand einen praxistip in der
schublade):

ich brauche ein zentrales konfigurationsobjekt, das per default
"public" paar standard variablen bereitstellt.

bislang war das so:

public class Config {
public strDB_Host=...
public strDB_User=...
private Config cfg=null;

private Config() {};

public static getConfig()
if (cfg==null)
cfg=new Config();
return cnf;
}

jetzt hat sich aber herausgestellt, dass in den projekten eine menge
gleich ist (konfiguration der datenbank und logfiles und sonstigen
kram).

und das wollte ich jetzt in eine abstrakte superklasse packen und die
subklasse dann ihr zusätzliches werk tun.

Paul Ebermann

unread,
Nov 12, 2002, 2:20:01 PM11/12/02
to
"bernd hohmann" skribis:

> siehe betreff:
>
> ich will mir mit einer statischen methode ein singleton meiner
> abstrakten klasse abholen.
>
> gibt es da strategien dafür ?

Ich habe das bisher noch nicht gemacht ...

Prinzipiell muss ja die statische Methode (oder
wer auch immer) beim Erstellen des Singletons
wissen, welche Subklasse zu benutzen ist.

Die Information könnte etwa aus einer
System-Property stammen.

Als Beispiele in der Standard-API fällt mir
jetzt java.awt.Toolkit sowie java.lang.Runtime
ein, mit ihren getDefaultToolkit() bzw.
getRuntime()-Methoden.

Vielleicht kannst du dir mal den Quelltext
davon ansehen.

Paul

michael paap

unread,
Nov 12, 2002, 3:53:24 PM11/12/02
to
bernd hohmann wrote:

> konkret geht es darum (vielleicht hat jemand einen praxistip in der
> schublade):
>
> ich brauche ein zentrales konfigurationsobjekt, das per default
> "public" paar standard variablen bereitstellt.
>
> bislang war das so:
>
> public class Config {
> public strDB_Host=...
> public strDB_User=...
> private Config cfg=null;
>
> private Config() {};
>
> public static getConfig()
> if (cfg==null)
> cfg=new Config();
> return cnf;
> }
>
> jetzt hat sich aber herausgestellt, dass in den projekten eine menge
> gleich ist (konfiguration der datenbank und logfiles und sonstigen
> kram).
>
> und das wollte ich jetzt in eine abstrakte superklasse packen und die
> subklasse dann ihr zusätzliches werk tun.


Hmmm. Wenn ich Dich recht verstehe, dann ist Dein Problem, dass Du gerne
eine abstrakte statische Create- Methode deklarieren würdest um damit
den Subklassen aufzuzwingen, dass sie diese implementieren. Den Wunsch
hatte ich auch schon, musste aber zur Kenntnis nehmen, dass es nicht geht.

Das einfachste dürfte wohl sein, zwei Configklassen zu haben, eine, die
in allen Deinen Projekten gleiche Attribute enthält und eine, die
jeweils unterschiedlich ist.

Gruß,
Michael

--
Mail-Antworten auf Postings bitte an:
newsreply@<Absender-Domain>.

Andreas Jaeger

unread,
Nov 12, 2002, 7:15:57 PM11/12/02
to
Vielleicht noch als Alternative, wenn es nur um
die zentrale Erreichbarkeit des Objektes geht:

public abstract class Config {

private static Config config;

protected Config() {
setConfig(this);
}

private static synchronized void setConfig(Config config) {
if (config != null)
throw new IllegalStateException();
Config.config = config;
}

public static void getConfig() {
return config;
}

}

--
---------------------------------------------
Andreas Jaeger
http://ifai.uni-muenster.de
AFI - Institut für Agrar- und Forstinformatik
an der Universität Münster
---------------------------------------------

Alexander Elsholz

unread,
Nov 13, 2002, 3:15:38 AM11/13/02
to
Hi,

michael paap wrote:
> Hmmm. Wenn ich Dich recht verstehe, dann ist Dein Problem, dass Du gerne
> eine abstrakte statische Create- Methode deklarieren würdest um damit
> den Subklassen aufzuzwingen, dass sie diese implementieren. Den Wunsch
> hatte ich auch schon, musste aber zur Kenntnis nehmen, dass es nicht geht.
>
> Das einfachste dürfte wohl sein, zwei Configklassen zu haben, eine, die
> in allen Deinen Projekten gleiche Attribute enthält und eine, die
> jeweils unterschiedlich ist.
>

oder auf 1.5 zu warten, wo das hoffentlich implementiert wird...

mfg alex

Ingo R. Homann

unread,
Nov 13, 2002, 4:50:40 AM11/13/02
to
Hi!

bernd hohmann schrieb:
> ...


> bislang war das so:
>
> public class Config {
> public strDB_Host=...
> public strDB_User=...
> private Config cfg=null;
>
> private Config() {};
>
> public static getConfig()
> if (cfg==null)
> cfg=new Config();
> return cnf;
> }
>
> jetzt hat sich aber herausgestellt, dass in den projekten eine menge
> gleich ist (konfiguration der datenbank und logfiles und sonstigen
> kram).
>
> und das wollte ich jetzt in eine abstrakte superklasse packen und die
> subklasse dann ihr zusätzliches werk tun.

Dann würde ich es entweder wie Sven machen, oder so lösen:

public abstract class Config {

public strDB_Host=...
public strDB_User=...
private Config cfg=null;

public static getConfig()
if (cfg==null)
cfg=new SubConfig();
return cnf;
}

private static SubConfig cfg;

}

class SubConfig extends Config {

protected SubConfig() {}

public String irgendwas=...

}

Hat natürlich den Nachteil, daß die Superklasse nicht ohne die konkrete
Implementierung der SubKlasse compilierbar ist (*), aber den Vorteil,
dass es nicht zu den merkwürdigen Reflection-Exceptions von Svens Lösung
kommen kann.

(*) Obwohl man zum vorcompilieren ja eine leere Default-Implementierung
mitliefern könnte, die dann bei Bedarf überschrieben wird...

Ciao,
Ingo

Ingo R. Homann

unread,
Nov 13, 2002, 5:01:35 AM11/13/02
to
Hi!

Andreas Jaeger schrieb:


> Vielleicht noch als Alternative, wenn es nur um
> die zentrale Erreichbarkeit des Objektes geht:
>
> public abstract class Config {
>
> private static Config config;
>
> protected Config() {
> setConfig(this);
> }
>
> private static synchronized void setConfig(Config config) {
> if (config != null)
> throw new IllegalStateException();
> Config.config = config;
> }
>
> public static void getConfig() {
> return config;
> }
>
> }

Mein erster Gedanke: "Häää? Im Konstruktor eine statische setMethode
aufrufen, die auch noch eine IllegalStateException werfen kann?"

Und dann, etwas später... "Genial!"

Und jetzt: "Wie stellst Du sicher, daß überhaupt mal irgendwann (und
dann auch noch genau ein mal!) der leere Konstruktor der SubKlasse
aufgerufen wird?"

Ciao,
Ingo

Patrick Roemer

unread,
Nov 13, 2002, 5:02:04 AM11/13/02
to
Hallo,

Alexander Elsholz wrote:

Bernds Configklassen oder abstrakte statische Methoden? ;)

Falls letzteres: Hast Du da mal einen Link zu?

Viele Gruesse,
Patrick

Patrick Roemer

unread,
Nov 13, 2002, 5:06:46 AM11/13/02
to
Hallo,

Paul Ebermann wrote:

>>ich will mir mit einer statischen methode ein singleton meiner
>>abstrakten klasse abholen.
>>
>>gibt es da strategien dafür ?

[...]


> Als Beispiele in der Standard-API fällt mir
> jetzt java.awt.Toolkit sowie java.lang.Runtime
> ein, mit ihren getDefaultToolkit() bzw.
> getRuntime()-Methoden.
>
> Vielleicht kannst du dir mal den Quelltext
> davon ansehen.

Naja... ;)

| private static Runtime currentRuntime = new Runtime();
|
| public static Runtime getRuntime() {
| return currentRuntime;
| }

Viele Gruesse,
Patrick

Thomas Bensler

unread,
Nov 13, 2002, 5:42:51 AM11/13/02
to
Ingo R. Homann wrote:
> Und jetzt: "Wie stellst Du sicher, daß überhaupt mal irgendwann (und
> dann auch noch genau ein mal!) der leere Konstruktor der SubKlasse
> aufgerufen wird?"

In die Doku schreiben und der IllegalStateException eine sinnige
Nachricht mitgeben ("Do not create more than one Config object!"). Man
kann halt nicht *alles* zur Compile-Zeit regeln ... :-/ .

Ciao, Thomas.

Ingo R. Homann

unread,
Nov 13, 2002, 5:58:55 AM11/13/02
to
Hi!

Thomas Bensler schrieb:


> Ingo R. Homann wrote:
>
>> Und jetzt: "Wie stellst Du sicher, daß überhaupt mal irgendwann (und
>> dann auch noch genau ein mal!) der leere Konstruktor der SubKlasse
>> aufgerufen wird?"
>

> In die Doku schreiben...

Ja, so eine Antwort hatte ich erwartet! ;-)

> Man
> kann halt nicht *alles* zur Compile-Zeit regeln ... :-/ .

Doch, siehe meine andere Lösung! :-)

> Ciao, Thomas.

Ciao,
Ingo

Andreas Jaeger

unread,
Nov 13, 2002, 12:13:40 PM11/13/02
to
Ingo R. Homann wrote:
> Hi!
>
> Andreas Jaeger schrieb:
>
>> Vielleicht noch als Alternative, wenn es nur um
>> die zentrale Erreichbarkeit des Objektes geht:
>>
>> public abstract class Config {
>>
>> private static Config config;
>>
>> protected Config() {
>> setConfig(this);
>> }
>>
>> private static synchronized void setConfig(Config config) {
>> if (config != null)
>> throw new IllegalStateException();
>> Config.config = config;
>> }
>>
>> public static void getConfig() {
>> return config; }
>>
>> }
>
>
> Mein erster Gedanke: "Häää? Im Konstruktor eine statische setMethode
> aufrufen, die auch noch eine IllegalStateException werfen kann?"
>
> Und dann, etwas später... "Genial!"

Das Wichtige ist doch das "synchronize". Im Prinzip hätte man es
ja auch so schreiben können:

private static Config config;
protected Config() {

synchronized (Config.class) {
if (config != null) ...
config = this;
}
}

Aber ich bin ein Freund der Symmetrie, daher _zwei_ statische
Methoden.
Andreas

Andreas Jaeger

unread,
Nov 13, 2002, 12:38:25 PM11/13/02
to
Auf Deinen eigentlichen Kommentar hätte ich vielleicht auch noch
eingehen sollen.

> Und jetzt: "Wie stellst Du sicher, daß überhaupt mal irgendwann (und
> dann auch noch genau ein mal!) der leere Konstruktor der SubKlasse
> aufgerufen wird?"

"Überhaupt irgendwann" stelle ich gar nicht sicher. Meine Erfahrung mit
nicht geladenen Konfigurationen ist: das merkt man ziemlich schnell.
Ich glaube nicht, dass man alles im Code auf Krampf absichern muß. Ich
bemühe mich eher, versehentlichen Fehlern vorzubeugen, besonders
solchen, deren eigentliche Ursache lange verdeckt bleiben könnte.

"Genau einmal" stelle ich insofern sicher, als ein zweiter Aufruf
irgendeines Konstruktors irgendeiner Subklasse dazu führt, dass
eine IllegalStateException geworfen wird. Denn am Konstruktor der
Superklasse geht kein Weg vorbei.

Was Du mit "leerer" Konstruktor der Subklasse meinst, weiß ich nicht.
Meinetwegen kann der auch Parameter haben.

Andreas

Paul Ebermann

unread,
Nov 13, 2002, 2:25:09 PM11/13/02
to
"Andreas Jaeger" skribis:

> Vielleicht noch als Alternative, wenn es nur um
> die zentrale Erreichbarkeit des Objektes geht:
>
[...]

> private static synchronized void setConfig(Config config) {
> if (config != null)
> throw new IllegalStateException();

Hier sollte aber bestimmt

if(Confog.config != null)

stehen, oder ich habe das nicht verstanden.

Paul

Paul Ebermann

unread,
Nov 13, 2002, 4:15:19 PM11/13/02
to
"Patrick Roemer" skribis:

Mist, hatte ich das falsch in Erinnerung.
Runtime ist nicht abstract, damit spielt
das hier keine Rolle.

Der Text bei java.awt.Toolkit.getDefaultToolkit()
hilft mehr.

Paul

Ortwin Glück

unread,
Nov 13, 2002, 5:58:25 PM11/13/02
to
bernd hohmann wrote:
> konkret geht es darum (vielleicht hat jemand einen praxistip in der
> schublade):
>
> ich brauche ein zentrales konfigurationsobjekt, das per default
> "public" paar standard variablen bereitstellt.
> jetzt hat sich aber herausgestellt, dass in den projekten eine menge
> gleich ist (konfiguration der datenbank und logfiles und sonstigen
> kram).
>
> und das wollte ich jetzt in eine abstrakte superklasse packen und die
> subklasse dann ihr zusätzliches werk tun.

Ich habe die Erfahrung gemacht, dass "zentrale Config Klassen" (also
Objekte, die alle Applikationsparameter kapseln) kein gutes Pattern ist.
Es führt nämlich dazu (oder verleitet zumindest dazu), dass dieses
Objekt extrem vielen Klassen referenziert wird. Es bildet sozusagen ein
Rückgrat quer durch die ganze Applikation. Es verbindet damit Klassen
(oder ganze Packages), die eigentlich gar nichts miteinander zu tun
haben. Das will man nicht.

Mein "Konfigurationspattern" sieht daher genau andersrum aus.
Es gibt ein Objekt, das die Parameter enthält, aber keinerlei Logik.
Also ein reines "struct" (ja nach belieben public Members oder
Beanstyle). Ich nenne dieses Objekt Configuration.

Dann gibt es den Configurator. Diese Klasse weiss was sie mit der
Configuration tun soll. Sie füttert diese an die unterschiedlichsten
Stellen (Configurator Ziele) der Applikation:
- parametriert eine DatasourceFactory beim Datenbankservice
- initialisiert Log4J
- modifiziert den UIManager von Swing mit den Farben des Skins
- etc.

Oft sind die zu konfigurierenden Komponenten Singletons, Factories oder
statische Variablen in irgendwelchen Klassen, oder System-Properties
oder ähnlich. Als Faustregel gibt es pro Package etwa ein Configurator
Ziel.

So müssen die Packages ihre konfiguration nicht holen, sonder sie werden
konfiguriert. Das erhöht die Trennung zwischen den Komponenten.

HTH

Odi

0 new messages