I'm looking to create a singleton in Delphi. I've done this before using older versions of Delphi, and ended up using global variables (in the implementation section) and using initialization and finalization to take care of the instance. Also there was no way of preventing the user from creating an instance as you couldn't hide the standard constructor. I was wondering if any of the new features such as class constructors and destructors, and class variables (ok, not so new), perhaps generics, could help in creating a generic singleton class. I haven't managed to create something to my satisfaction yet.
The most popular approach is to implement a Singleton by creating a regular class and making sure it has: A private constructor. A static field containing its only instance. A static factory method for obtaining the instance.
The most important drawback of the singleton pattern is sacrificing transparency for convenience. Consider the earlier example. Over time, you lose track of the objects that access the user object and, more importantly, the objects that modify its properties.
To create the singleton class, we need to have static member of class, private constructor and static factory method. Static member: It gets memory only once because of static, itcontains the instance of the Singleton class. Private constructor: It will prevent to instantiate the Singleton class from outside the class.
I prefer to use interfaces when I need singletons and hide the implementation of the interface in the implementation section.
benefits
drawbacks
Note: I believe the use of Singletons should be kept to an absolute minimum. All in all, Singletons are little more than glorified global variables. If and when you start unit testing your code, they become a nuisance.
unit uSingleton;
interface
type
ISingleton = interface
['{8A449E4B-DEF9-400E-9C21-93DFA2D5F662}']
end;
function Singleton: ISingleton;
implementation
uses
SyncObjs;
type
TSingleton = class(TInterfacedObject, ISingleton);
var
Lock: TCriticalSection;
function Singleton: ISingleton;
const
_singleton: ISingleton = nil;
begin
if not Assigned(_singleton) then
begin
Lock.Acquire;
try
if not Assigned(_singleton) then
_singleton := TSingleton.Create();
finally
Lock.Release;
end;
end;
Result := _singleton;
end;
initialization
Lock := TCriticalSection.Create;
finalization
Lock.Free;
end.
There is a way to hide the inherited “Create” constructor of TObject. Although it is not possible to change the access level, it can be hidden with another public parameterless method with the same name: “Create”. This simplifies the implementation of the Singleton class tremendously. See the simplicity of the code:
unit Singleton;
interface
type
TSingleton = class
private
class var _instance: TSingleton;
public
//Global point of access to the unique instance
class function Create: TSingleton;
destructor Destroy; override;
end;
implementation
{ TSingleton }
class function TSingleton.Create: TSingleton;
begin
if (_instance = nil) then
_instance:= inherited Create as Self;
result:= _instance;
end;
destructor TSingleton.Destroy;
begin
_instance:= nil;
inherited;
end;
end.
I added the details to my original post: http://www.yanniel.info/2010/10/singleton-pattern-delphi.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With