|
Community Links |
Interessengemeinschaften |
Benutzerliste |
Foren durchsuchen |
Stichwortsuche |
Erweiterte Suche |
Uns unterstützen |
Shoppen bei Amazon |
Spende per Patreon |
Spende per PayPal |
Spende per Steady |
alle Möglichkeiten |
Gehe zu... |
|
Themen-Optionen | Ansicht |
2004-11-28, 18:52:19 | #1 (im Thread / einzeln) |
Gold Member
Registriert: 2003-08-12
Beiträge: 733
|
Problem mit singleton unter java
Hi
ich hab eine Singleton Klasse mit Namen Data erzeugt und möchte nun verhindern daß eine 2. Instanz erzeugt werden kann wenn schon eine erzeugt wurde.Kann mir da einer weiterhelfen wie ich das realisieren könnte? Hier der Code: final class Data { private String name; // create the one and only object “in store” private static Data theData = new Data ("NoName"); // a private constructor private Data (String n) {this.name = n;} // a reference to the object public static Data createData() { return theData; } // other methods of class Data public void setName (String n) { name = n; } public String getName () { return name; } } Geändert von lola (2004-11-28 um 20:17:52 Uhr) |
2004-11-28, 21:34:14 | #2 (im Thread / einzeln) |
Admiral Member
Registriert: 2003-03-27
Beiträge: 3.357
|
Re: Problem mit singleton unter java
Tuts du ja schon. Der Konstrukor ist private, also wird verhindert, dass er von ausserhalb der Klasse aufgeraufen wird.
Ist im Moment nicht lazy aber das ist ja nicht Voraussetzung für ein singelton. BTW, [ code ] Tags regeln. |
2004-11-28, 22:14:25 | #4 (im Thread / einzeln) |
Admiral Member
Registriert: 2003-03-27
Beiträge: 3.357
|
Re: Problem mit singleton unter java
Sorry, aber genau dieser Code beweist, das du eben nicht neue Instanzen kreierst. Wie denn auch, createData verwendet ja auch nicht new sondern gibt bloss eine Klassenvariable, die zufälligerweise die singleton Instanz ist zurück.
Falls du mir immer noch nicht glaubst: update: Es geht eigentlich schon, aber nicht mit deinem Code und ich glaube nicht, dass du das meintest. Wenn du das verhindern willst, musst du entweder einen SecurityManager verwenden, der das verbietet oder im Konstrukor einen check machen, ob die singleton Instanz schon kreiert wurde. Falls ja wirfst du eine Exception. Geändert von HellHorse (2004-11-29 um 14:58:45 Uhr) |
2004-11-30, 11:22:08 | #7 (im Thread / einzeln) |
Admiral Member
|
Re: Problem mit singleton unter java
Den Check auf null macht man doch in der Factory-Methode.
Wenn du die Instanzierung in der Factory vornimmst, hast du den Vorteil über die Factory z.B. einen überladenen Konstruktor aufzurufen. Allerdings ist das Bsp. nicht Threadsafe. Wie das in Java Threadsafe implementiert wird, weiß ich nicht. Geändert von grakaman (2004-11-30 um 11:45:47 Uhr) |
2004-11-30, 12:14:58 | #8 (im Thread / einzeln) |
Admiral Member
Registriert: 2003-03-27
Beiträge: 3.357
|
Re: Problem mit singleton unter java
Wenn du es lazy willst, dann schon.
update: Der check im Konstruktor war nur für den Fall gedacht, dass sich jemand den private Konstruktor über Reflection schnappt, als accessible marktiert und dann aufruft. Wie schon gesagt, auch dieser Test lässt sich aushebeln. Kannst du sonst auch machen. synchronzied und gut ist. Geändert von HellHorse (2004-11-30 um 12:36:08 Uhr) |
2004-11-30, 14:03:00 | #10 (im Thread / einzeln) |
Admiral Member
Registriert: 2003-03-27
Beiträge: 3.357
|
Re: Problem mit singleton unter java
Normalerweise (so wie du es gepostet hast, und nicht so wie lola es gepostet hat) ist ein singleton lazy initialized. Will heissen die singleton Instanz wird erst kreiert, wenn das erste mal jemand die factory Methode aufruft und nicht schon wenn die Klasse geladen wird, daher ist auch der check nötig. Das ist aber nicht Anforderung an ein singleton.
Hoffe wir reden vom gleichen: Anmerkung zu Update2: Das Aushebeln geht allerdings nur, wenn theData nicht final ist. Geändert von HellHorse (2004-11-30 um 14:04:59 Uhr) |
2004-11-30, 14:21:42 | #11 (im Thread / einzeln) |
Admiral Member
|
Re: Problem mit singleton unter java
Na ich meinte eigentlich, wenn man in der/den Factory(s) die Instanz erstellt (deswegen heißt die wohl auch Factory), kann der, der die Klasse von "draußen" aufruft, festlegen mit welchen Konstruktor er sie initialisieren will. Das kann ich ja logischerweise nicht machen, wenn ich, wie lola, das Feld fest auf Klassenebene instanziere.
Geändert von grakaman (2004-11-30 um 14:22:53 Uhr) |
2004-11-30, 15:15:28 | #12 (im Thread / einzeln) |
Admiral Member
Registriert: 2003-03-27
Beiträge: 3.357
|
Re: Problem mit singleton unter java
Theoretisch, aber wie schon gesagt, bloss beim ersten mal, wenn die singleton Instanz noch nicht erstellt wurde. Falls sie schon besteht, geht es nicht. Es gibt also keine Garantie, dass es hinaut und ist daher sehr gefährlich. Und eigentlich ist es ja die Idee einer factory Methode unter anderem von solchem Zeugs, wie welcher Konstruktor verwendet wird zu abstrahieren.
Auf Klassenebene kannst du immer noch so was machen: Geändert von HellHorse (2004-11-30 um 15:19:27 Uhr) |
2004-11-30, 15:57:33 | #13 (im Thread / einzeln) |
Admiral Member
|
Re: Problem mit singleton unter java
Aber genau das machst du doch mit der Factory Klasse. Du bräuchtest ja auch keine Factory Klasse, wenn du die Instanzierung des Feld auf Klassenebene durchführst. Dann könntest du das Feld gleich public machen.
Die Sache ist jetzt die, dass du das Singleton beliebig instanzieren willst. Das verbietet ja ein Singleton nicht, es geht ja nur darum für einen bestimmten Zeitraum nur eine Instanz zu garantieren. Aber genau so gut könntest du ja in der Klasse eine statische Methode implementieren, die die Instanz wieder löscht. Nur wenn du die Instanzierung in einer extra Methode vornimmst, (Factory) kannst du von Außerhalb das Singleton mit beliebigen Konstruktoren aufrufen. Und in deinem Bsp. mag das zwar so gehen, aber wenn du verschiedene Konstruktoren mit unterschiedlichen Parametern hast, dann müssen die ja auch irgendwo herkommen. Und dann für alle Parameter noch Instanzfelder deklarieren werden und ggf. noch Getter- und Setter-Methoden, anstatt die gleich nur einer Methode zu übergeben und dort die Instanzierung vorzunehmen, sieht mir das ziemlich umständlicher aus. Aber im Endeffekt kann ich das auch nur so sagen, wie ich es eben immer gelesen habe. Kann sein, dass man das eben bei Java anders macht. Geändert von grakaman (2004-11-30 um 16:00:11 Uhr) |
2004-11-30, 16:47:45 | #14 (im Thread / einzeln) |
Admiral Member
Registriert: 2003-03-27
Beiträge: 3.357
|
Re: Problem mit singleton unter java
Ich kann ja auch später eine andere Klasse im static initializer instanzieren, kein Problem.
Nein, es darum sicherzustellen, dass von einer Klasse, bloss eine Instanz existiert. Schlag sonst noch einmal in Design Patterns nach. Wenn dir deine Sprache erlaubt zu zählen wieviele Pointer auf ein Objekt existieren. Java tut es z.B nicht. Sollst du aber nicht können. Darum ist der Konstruktor auch private. Das hat aber nix damit zu tun, wann das singleton kreiert wird. Ich verweise hier noch einmal auf Design Patterns. Öh ja, der Konstruktor muss schon irgend woher kommen. Aber ich sehe nicht genau was du willst. Die Initialisation in der factory Methode statt im Konstruktor vornehmen oder was? "Eigentlich" macht man es schon so, wie du es gepostet hast. Bloss muss es halt eben nicht lazy sein, damit es ein singleton ist. Geändert von HellHorse (2004-11-30 um 16:48:22 Uhr) |
2004-11-30, 18:37:20 | #15 (im Thread / einzeln) |
Admiral Member
|
Re: Problem mit singleton unter java
Der Konstruktor ist private, damit nicht beliebig viele Instanzen erstellt werden können, sondern nur eine. Das hat aber nun nichts damit zu tun, dass keiner von außerhalb das Objekt instanzieren bzw. verschieden initialisieren darf. Es muss lediglich gewährleistet werden, dass eben von der Klasse nur eine Instanz vorhanden ist. Wer da den Anfgang macht, ist ja unerheblich. Und das muss ja auch nicht die komplette App-Lebenszeit betreffen. Ich kann ja genau so ein System implementieren, dass auf ein Ereignis plötzlich komplexe Operationen macht und während dessen, sollen alle partizipierenden Objekte auf ein und die selbe Instanz zugreifen. Wenn die Operation fertig ist und ein neues Ereignis ausgelöst wird, möchte ich vielleicht ein anders initialisiertes Singleton Objekt, bei dem auch wieder alle partizipierenden Teilobjekte nur auf eine Instanz zugreifen sollen. Das ganze kann ja voll und ganz sequenziell ablaufen, dabei muss es sich doch nicht zwangsweise um irgend welche Remoteobjekte handeln, auf das mehrere Clients gleichzeitig zugreifen.
Geändert von grakaman (2004-11-30 um 19:00:37 Uhr) |
2004-11-30, 20:31:40 | #16 (im Thread / einzeln) |
Admiral Member
Registriert: 2003-03-27
Beiträge: 3.357
|
Re: Problem mit singleton unter java
Der Konstruktor ist private, damit "von aussen" keine Objekte generiert werden können.
Doch. Schau dir mal die Anmerkungen zur C++ Implementation in Design Patterns doch noch einmal an. Die sind diesbezüglich sehr klar. Eben, es muss nicht lazy sein. Und was machst du, wenn jemand irgendwo noch eine Referenz auf das "alte" singelton hat? Muss nicht remote sein. Klar, in Smalltalk kannst du z.B. alle Pointer, die auf ein best. Objekt zeigen auf ein anderes Zeigen lassen wenn du bloss das referenzierte Objekt kennst. Java erlaubt dir solche Spässe nicht. |
2004-11-30, 23:08:53 | #17 (im Thread / einzeln) |
Admiral Member
|
Re: Problem mit singleton unter java
Hier mal ein Zitat aus dem Buch "Enterprise Solutions Patterns using Microsoft.NET":
zu static Initialization bei Singleton: ...The only downside of this approach is that you have less control over the mechanics of the instantiaten. In the Design Pattern form, you were able to use a nonedefault constructor or perform other tasks before the instantiation.. Wie gesagt, es schreibt ja niemand vor für wie lange die Instanz erhalten sein soll, sie muss nur für einen bestimmten Zeitraum eben für alle Objekte gelten. Das kann für immer sein oder eben nur für einen bestimmten Zeitraum und danach erstellt die Software vielleicht eine veränderte Instanz, die jetzt plötzlich gelten muss. Bsp.: Ich habe einen Puffer, der bestimmte Daten sammeln soll und immer ausgeben soll. Vielleicht möchte ich ein Programm starten und zuvor den Puffer individuell anpassen (Größe, Ausgabetyp Konsole/Popup etc.). Oder es werden regelmäßig recht komplexe Operationen getriggert (sequenziell) und vor jedem Aufruf muss aber das alte Singleton gelöscht werden und ein anderes instanziert und initialisiert werden. Das ganze könnte natürlich auch parallel passieren, z.B. in verschiedenen App Domains (.NET) oder eben Prozessen. Oder man will einfach nur für einen bestimmten Zeitraum aus performancegründen die Instanzierung von mehreren gleichen Objekten verhindern. Es gibt da recht viele Anwendungsmöglichkeiten für ein Singleton, ich würde das nicht ganz so eng sehen. Geändert von grakaman (2004-11-30 um 23:10:29 Uhr) |
2004-12-01, 12:30:48 | #18 (im Thread / einzeln) |
Admiral Member
Registriert: 2003-03-27
Beiträge: 3.357
|
Re: Problem mit singleton unter java
Es geht hier weder um "Enterprise Patterns" noch um .NET
Natürlich ist statische Initialisierung weniger flexibel, das bestreite ich ja auch nicht. Aber gerade dadurch dass lola ja die statische Methode verwendet um auf das singleton zuzugreiffen anstatt das Feld public zu machen, behält er sich ja die Flexibilität das später zu ändern ohne dass es Änderungen in anderen Klassen erfordert. |
Lesezeichen |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
|
|