Two Delphi implementation Singleton mode method
Haozi
Abstract This article describes the Delphi implementation of two Singleton modes, and has made comparative analysis. Keyword design pattern, Singleton
Singleton mode is a very useful design pattern. Its intent is: Just create an instance of a class and provide a global access point access to it. A global variable makes an object easy to access, but it is not possible to prevent you from instantiating multiple objects. The purpose of single-piece mode is to ensure that there is only one instance in the life cycle of the program. Look at the following code: Procedure TForm1. Button1click (Sender: TObject); var ls1: tsingleton; ls2: tsingleton; begin try ls1: = tsingleton.create; call class constructor LS2: = tsingleton.create; Call class constructor ... other code finally ls1.free; release the object ls2.free; release the object end; End;
The Tsingleton class is instantiated when the CREATE function is called in the previous code, and the LS1 points to a memory address of the object. When the Tsingleton.create function is called the second time, the Tsingleton object is re-instantified, and the LS2 points to memory allocation. Another address. Singleton mode is to let the class be responsible for saving his only example.
In the above code, the LS2 is also intended to point to the LS1 (that is, the same memory address is assigned), and we must prevent memory from being released when the LS1 is released, as the single object is also referenced by LS2. This ensures that there is only one class instance in the life cycle of the program. "Design Mode" C sample code is saved using a static member variable of C , while using protected constructor functions. However, in Delphi, since there is no static member variable, it is not possible to use the method of using the single mode example. Here we analyze several ways to implement the Singleton mode of Delphi.
One. Method for two TOBJECT virtual functions based on Override
Class function newinstance: TOBJECT ;VIRTUAL; Procedure FreeInstance; Virtual; NewInStance function is responsible for the object to allocate memory when it is created, FreeInstance reverse memory
. The former is called when the object constructs, and the latter is called when an object destructure. We use two global variables to save the reference number of single objects and objects. VAR Instance: Tsingleton = NIL; Refcount: Integer = 0;
Tsingleton class unit: ------------------------------------------- ------------------------------
Unit usingleton;
Interface
TYPE TSINGETON = Class (TOBJECT) PUBLIC CLASS FUNCTION NEWINSTANCE: TOBJECT; OVERRIDE; overlay base class function procedure freeInstance; override; overlay base class function Class Function Refcount: integer; Returns the current reference count end;
Declaration Global Variablesvar Instance: Tsingleton = NIL; Refcount: Integer = 0;
IMPLEMENTATION
{Tsingleton}
Procedure Tsingleton.FreeInstance; Begin Dec (Refcount); Reduce the reference count if (refcount = 0) THEN is 0, is the release of the memory begin instance: = nil; release the private variable of the single piece ... Inherited FreeInstance; End; End; ;
class function TSingleton.NewInstance: TObject; begin if (not Assigned (Instance)) then begin Instance: = TSingleton (inherited NewInstance); private variable initialization example: Instance.VariableName: = Value; end; Result: = Instance; Inc (RefCount END;
Class function tsingleton.refcount: integer; begin result: = refcount;
End. -------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------
When calling Tsingleton's constructor, we call our Override's NewInstance function, allocate memory by NewInstance and return to the constructor, so that through Override's NewInstance function we ensure that the Create function can only instantiate a Tsingleton object (no matter how many times CREATE only returns the first assigned memory address). At the same time, the RefCount variable saves us several to object references.
Let's see the test code
procedure TForm1.Button1Click (Sender: TObject); var lS1, lS2: TSingleton; Ob1, Ob2: Tobject; begin lS1: = TSingleton.Create; ShowMessage (IntToStr (RefCount)); Ref_Count = 1 lS2: = TSingleton.Create; ShowMessage (INTSTR (REFCOUNT); ref_count = 2 ob1: = Tobject.create; ob2: = Tobject.create; if ls1 = ls2 Then ShowMessage ('address equal') LS1 = LS2 Else showMessage ('address is not equal); if OB1 = ob2 Ten ShowMessage ('address equal') Else showMessage ('address is not equal "; OB1 <> OB2END; when the program calls the destructor (when calling the free function), the destructor calls the FreeInstance function. Release the memory allocated by the constructor. Override's FreeInstance function guarantees that the memory of the single-piece mode object is released when the reference count is zero. Here is our test code: Var ls1: tsingleton; ls2: tsingleton; begin try ls1: = tsingleton.create; call class constructor ls2: = tsingleton.create; call class constructor ... other code Finally LS1 This will first call us to override the defined FreeInstance, because Refcount is 1 after 1, the single object is not released LS2.Free; dec (refcount) = 0 releases the single piece object end; end; above Single-piece mode implementation methods are well implemented by class itself to save their own unique instances (by intercepting requests for creating new objects - refer to "Design Mode". It does not have special limitations for Tsingleton class Create and free functions can be invoked at will. The disadvantage of this mode is that the TSINGleton class cannot be used as a parent class inheritively generating a subclass. If inherits generates two subclasses, only one object is generated .Procedure TFORM1.BUTTON1CLICK (Sender: TOBJECT VAR LS1: Sub-class one; LS2: Sub-class 2; begin LS1: = subclass 1.create; ls2: = subclass 2 .create That is, LS1 = LS2END;
two. The Delphi implementation of the "Design Mode" on "Design Mode" is an implementation example of the implementation of a private constructor that implements only an object instance. But the given C code implementation does not give the object how to release it. Delphi cannot implement the privatization of the Create function, we newly define a function instead of the create function while blocking the Create function of the parent class. code show as below
: ------------------------------------------------- ----------------------------
Unit usingletonunit;
InterfaceUses Classes, Sysutils; Type
Tcsingleton = Class (TComponent) inherited from the Tcomponent class. privateconstructor CreateInstance (AOwner: TComponent); passing Owner parameters such TCSingleton class object will be destroyed along with the Owner (owner is responsible for the destruction of TCSingleton objects) public constructor Create (AOwner: TComponent); override; class function Instance (AOwner: TComponent): TCSingleton End; Var gcsingleton: Tcsingleton; Global Variables
IMPLEMENTATION
{TCSINGLETON}
Constructor tcsingleton.create (Aowner: Tcomponent); Begin masked create function Raise Exception.createfmt ('Access Class% s THROUGH Instance Only ", [ClassName]);
Constructor TcSingleton.createInstance (Aowner: Tcomponent); New Defined Constructor PRIVATETED CREATE (AOWNER);
Class Function TCSINGLETON.INSTANCE (AOWNER: TComponent): tcsingleton; begin if not assigned (gcsingleton) Then gcsingleton: = tcsingleton.createInstance (aowner); result: = gcsingleton;
End. -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------- /
/ During the implementation class of the above, the programmer does not need to consider the destruction problem of the single-piece mode object. Just invoke CREATE, you must call the Instance function to get an instance of an object, while passing the single owner as a parameter into a function. This implementation method can be inherited as a base class, in a single piece of state mode (see Reference 4), implementation, is implemented. three. Conclude
Singleton mode Delphi Delphi can also check some other implementations on the Internet, both of which
The most common and simple. At the same time, the idea of other methods is also very similar to the above two methods.
The above examples have not considered a multi-thread. Author email: wuch@km169.net
Reference: 1. "CREANG A REAL SINGLETON CLASS in Delphi" by lasse2. "Delphi 5 Developer Guide" Machinery Industry Press 2000.73. "Design Mode" Machinery Press 2000.94. "UML and Mode Application" Machinery Industry Press 2002.1, etc.