单例模式顾名思义就是一个实例,在任何情况下,系统中只能存在某一对象的一个实例。单例模式在应用开发中比较常见,如 Application 或 Logger。
在 Delphi 的以前版本中,实现单例模式比较“另类”,自从 Delphi 后期加入一些新的语法元素后,单例模式的实现显得更为标准,和 C++、Java 中的实现方法几乎一致,最主要原因就是 Delphi 加入了类变量的支持,关键字为”class var”。
Delphi 同时支持类属性,可以让单例的访问更为友好;同时需要注意,在实现单例模式时,一定不要忘记把类本身的 Create 构建函数隐藏,否则的话,单例的实现将没有意义。
下面的代码实现了单例模式的 TLogger:
unit LoggerService;
interface
uses
SysUtils, Windows, Messages, Classes, Forms, Dialogs;
type
TLogger = class(TObject)
private
class var
FInstance: TLogger;
class function GetInstance: TLogger; static;
protected
constructor Create;
public
procedure Login;
procedure Logout;
class procedure ReleaseInstance;
class property Instance: TLogger read GetInstance;
end;
implementation
{
************************* TLogger *************************
}
constructor TLogger.Create;
begin
ShowMessage('Create...');
end;
class function TLogger.GetInstance: TLogger;
begin
if FInstance = nil then FInstance := TLogger.Create;
Result := FInstance;
end;
procedure TLogger.Login;
begin
ShowMessage('Login...');
end;
procedure TLogger.Logout;
begin
ShowMessage('Logout...');
end;
class procedure TLogger.ReleaseInstance;
begin
FreeAndNil(FInstance);
end;
end.
通过 TLogger.Instance 属性即可访问日志记录对象的唯一实例,使用 TLogger.ReleaseInstance 释放实例,当然通过 TLogger.Instance.Free 也可释放实例,但在 FInstance 为 Nil 的时候,此种释放方法会先构建一个实例然后再释放,所以 ReleaseInstance 是最佳选择。 Delphi 支持全局变量,如果觉得 TLogger.Instance 这种访问方法显得麻烦,可以定义一个 Logger 全局变量来访问实例,如下:
...
interface
...
var
Logger: TLogger;
...
implementation
...
initialization
Logger := TLogger.Instance;
finalization
TLogger.ReleaseInstance;
Logger := nil;