![]() |
[Tutorial] Singletons in Delphi
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo alle miteinander,
ich habe heute mal ein kurzes Tutorial über Singletons in Delphi geschrieben. Das ganze umfasst eine kurze Erklärung über den Begriff "Singleton" und eine Beispielimplementierung. Ich habe versucht das ganze so einfach wie möglich zu halten :) Runterladen kann man das ganze hier und auf meinem Blog: ![]() |
Re: [Tutorial] Singletons in Delphi
Kurz und würzig, bravo und danke!
MfG |
Re: [Tutorial] Singletons in Delphi
Müsste das auf deiner Seite nicht download (pdf, 17kb) statt download (pfd, 17kb) heißen? :stupid:
|
Re: [Tutorial] Singletons in Delphi
Ich schließe mich da voll und ganz Aphton an.
|
Re: [Tutorial] Singletons in Delphi
Upala, stimmt, pdf, danke :)
|
Re: [Tutorial] Singletons in Delphi
Gutes Tutorial. :)
Zwei Anmerkungen hätte ich allerdings noch:
Delphi-Quellcode:
sollte besser nach "implementation" deklariert werden, damit der Entwickler nicht versehentlich direkt auf g_BK zugreifen kann.
var g_BK:Tbundeskanzler;
Der Delphi-Compiler schreibt zurecht eine Warnung aus, dass der Konstruktor nicht in private deklariert werden sollte. Am besten solle es so aussehen:
Delphi-Quellcode:
{$WARNINGS OFF}
constructor Create; {$WARNINGS ON} |
Re: [Tutorial] Singletons in Delphi
Oh okay, die Warnung bekommen ich in D7 nicht :) Danke für die Tips, werd's noch einarbeiten!
|
Re: [Tutorial] Singletons in Delphi
Das Tutorial kommt wie gerufen für mich :) Danke Dir...
SCRaT P.S.: Habe im Netz im Rahmen meiner Recherchen noch einen Singleton gefunden, in dem die Anzahl der Instanzen noch gespeichert wird, und wenn die letzte Instanz (d.h. InstanceCount = 0), dann wird der Speicher komplett freigegeben. Fand ich auch eine "schöne" Sache... |
Re: [Tutorial] Singletons in Delphi
Hallo,
folgendes ist mir aufgefallen: Zitat:
Zitat:
Statt dessen finde ich es sinnvoller im Destruktor eine Exception ausgelöst werden, damit niemand (aus Versehen oder absichtlich) die Singleton-Instanz zerstört.
Delphi-Quellcode:
Die Methode getInstance sollte nach Möglichkeit Threadsicher gestaltet werden, damit beim gleichzeitigen Zugriff durch zwei Threads beide die selbe Instanz erhalten:
destructor TBundeskanzler.destroy;
begin raise Exception.Create('Singleton darf nicht zerstört werden!'); end;
Delphi-Quellcode:
mr2
Function TBundeskanzer.getInstance:TBundeskanzler;
begin if (g_BK = nil) // statt TBundeskanzler.create reicht auch nur Create then InterlockedCompareExchange(g_BK, Create, nil); Result := g_BK; end; |
Re: [Tutorial] Singletons in Delphi
Zitat:
das widerspricht sich total. Von einem Singelton kann es nicht mehr als eine Instanz geben, sonst wäre es ja keines ..... |
Re: [Tutorial] Singletons in Delphi
in neueren Delphi-Versionen würde man aber statt der Variablen in der Unit eine class var benutzen ..
Delphi-Quellcode:
;
TBundeskanzler = class
private class var Bundeskanzler : TBundeskanzler; end |
Re: [Tutorial] Singletons in Delphi
Zitat:
|
Re: [Tutorial] Singletons in Delphi
Singletons sollte man durchaus kritisch sehen :warn:
Letztendlich handelt es sich dabei um globale Objekte; also im Prinzip das Gleiche wie globale Variablen. Globale Variablen und Singletons machen uns Programmierer das Leben schwer, weil sie unangenehme Seiteneffekte hervorrufen. Wer Englisch versteht sollte sich unbedingt mal dieses Video ![]() Es könnte die Meinung über Singletons grundlegend ändern... |
Re: [Tutorial] Singletons in Delphi
Ich finde das Tutorial gut, aber besser wäre es, wenn es sich noch an die Styleguidelines bezüglich Nomenklatur halten würde.
Felder beginnen mit 'f', keine 'ungarische Notation' bzw. Verklausulierung des Datentyps, und Underscores sollten vermieden werden. Zum Google-Video fällt mir nur ein, das es natürlich wichtig ist, auf die Gefahren hinzuweisen, die sich hinter solchen Praktiken verbergen, aber man muss schon die richtigen Schlüsse daraus ziehen. Die Dogmen der 'modernen' Softwareentwicklung sind wirklich sinnvoll: 1. Globale Variablen sind böse. Mein Programm ist eine globale Variable, ebenso alle Formulare und Datenmodule. 2. Goto's sind böse. Mein Programm besteht letztendlich aus (fast) nichts anderem. 3. Singletons sind böse. Neben dem Programm verzichte ich damit auf Caches, Dictionaries, Logger, Drucker, Festplatten und Bildschirme etc.. Oh, und letztendlich auf den User. Also ich weiss nicht. Ich LIEBE es, gegen Dogmen zu verstoßen. Und verdiene mein Geld damit. Allerdings auch nur deshalb, weil ich nicht inflatorisch gegen Dogmen verstoße. Ach so, bei jedem Argument gehört ein :stupid: und ein :mrgreen: dahinter, :zwinker: Zurück zum Tutorial: Ich würde folgenden Gegenvorschlag machen:
Delphi-Quellcode:
unit SingletonUnit;
interface type TSingleton = class protected // Verbergen der dem Singleton-Prinzip widersprechenden Methoden, so kann man dann nicht mal 'aus Versehen' // ein Singleton freigeben. constructor Create; destructor Destroy; procedure Free; public // Es ist nur das sichtbar, was das Singleton kann procedure PublicMethod(); end; // Automatische 'Lazy initialization' function Singleton: TSingleton; implementation var SingletonInstance: TSingleton; function Singleton: TSingleton; begin if SingletonInstance = nil then SingletonInstance := TSingleton.Create; Result := SingletonInstance; end; { TSingleton } constructor TSingleton.Create; begin inherited; end; destructor TSingleton.Destroy; begin inherited; end; procedure TSingleton.Free; begin inherited Free; end; procedure TSingleton.PublicMethod; begin // Do Something; end; initialization SingletonInstance := nil; finalization SingletonInstance.Free; end. |
Re: [Tutorial] Singletons in Delphi
Hi, danke für eure Hinweise :)
@mr2: InterlockedCompareExchange funktioniert nicht mit Create als 2. Parameter. Hast du das getestet? |
Re: [Tutorial] Singletons in Delphi
Hallo,
nochmal zum Problem mit dem Konstruktor: Es kann nichts mehr versteckt werden, was bereits in einer Elternklasse veröffentlich wurde. Man kann dann zwar nicht genau diesen Konstruktor aufrufen, trotzdem ist es möglich, eine Instanz dieser Klasse zu erzeugen. Besser ist es, wenn man soetwas macht:
Delphi-Quellcode:
Auf diesem Weg ist es nicht mehr möglich, eine Instanz dieser Klasse ohne den eigenen Konstruktor zu erzeugen.
TSingleton = class(TObject)
private constructor _Create(); public constructor Create(); end; {...} constructor TSingleton.Create(); begin raise Exception.Create('Use TSingleton.getInstance!'); end; constructor TSingleton._Create(); begin inherited Create; {...} end; |
Re: [Tutorial] Singletons in Delphi
Soweit ich das überschaue, bekommt man soetwas nicht bullet-proof hin, d.h. es ist immer möglich, das jemand mutwillig das Konzept unterminiert, z.B. durch Typecasting. Aber ich denke, darum muss man sich nicht kümmern, das ist imho etwas spitzfindig, denn wir entwickeln Klassen und Konzepte nicht für unsere Feinde, sondern Kollegen.
Es geht doch eher darum, das man ein Singleton nicht mehrfach instantiiert oder versehentlich freigibt, weil man das Konzept nicht begriffen hat, und nicht, das man es unter allen umständen verbietet. Dann würde ich -glaube ich- einen Sentinel schreiben, der alle Instanzen außer der ersten gnadenlos abschießt und den (End-)Benutzer mit einer entsprechenden Meldung verwirrt. Natürlich könnte man auch das wieder umgehen usw. Also, WTF. |
Re: [Tutorial] Singletons in Delphi
Darum gehts hier doch gar nicht. Wenn man nicht weiß, dass es sich um ein Singleton handelt, bekommt man es auch nicht mit, wenn man es mal mit TSingleton.Create aufruft.
Bei mir kommt eben ein Hinweis, wie man die Klasse richtig verwendet. Auch unter Kollegen kann so ein Hinweis ganz nett sein, bevor man ev. stundenlang den Fehler sucht, warum die Konfiguration oder sowas nicht korrekt geschrieben wird. Edith sagt: Hast du eigentlich schon mal folgendes probiert?
Delphi-Quellcode:
und dann in einer anderen Unit(!):
type
TSingleton = class(TObject) private constructor Create; end;
Delphi-Quellcode:
Das kompiliert ganz wunderbar, nur der aufgerufene Konstruktor ist der von TObject. Wunderbar, was? Und das alles ganz ohne Typecast.
var
s: TSingleton; begin s := TSingleton.Create; end; Und nochwas, ich versuche, meine Sachen immer so sicher wie möglich zu machen. Warum? Vielleicht habe ich ja eine Bibliothek oder Komponente erstellt, die ich mit Sourcecode weiterverteilen möchte. Und dann macht man es den Benutzern doch wesentlich einfacher, die eigene Arbeit korrekt zu verwenden. |
Re: [Tutorial] Singletons in Delphi
Echt? Ich hab nur in der Codevervollständigung keinen Vorschlag mehr für Create gefunden, glaub ich jedenfalls. :gruebel:
Wenn das gar nicht stimmt und nichts bringt, ist es natürlich für die Katz. Kennst Du denn eine absolut saubere Implementierung eines Singletons in Delphi? Ich glaub, das geht gar nicht. Delphi ist eben keine moderne Programmiersprache, in C# ist es mit einigen wenigen Zeilen Code getan. |
Re: [Tutorial] Singletons in Delphi
Zitat:
|
Re: [Tutorial] Singletons in Delphi
Sofern man Delphi 2010 zur Verfügung hat, finde ich
![]() |
Re: [Tutorial] Singletons in Delphi
Das Create scheint nicht das Problem zu sein, eher der erste Parameter.
So geht es bei mir unter Delphi 6:
Delphi-Quellcode:
mr2
InterlockedCompareExchange(Pointer(_Instance), Create, nil);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz