delphi的单例模式TSingleton

本文介绍了一种使用Delphi实现单例模式的方法。通过定义TSingleton类,并重写NewInstance和FreeInstance方法来确保在整个应用程序中只存在一个实例。此外,还提供了一个TForm1表单类作为示例。

type
  TSingleton = class
  public
    class function NewInstance : TObject;override;
    procedure FreeInstance;override;
  end;
  TForm1 = class(TForm)
    Button1: TButton;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  singleton:TSingleton=nil;
  Ref_Count:integer=0;
implementation

{$R *.dfm}

{ TSingleton }

procedure TSingleton.FreeInstance;
begin
  Dec(Ref_Count);
  if Ref_Count=0 then
  begin
    singleton := nil;
    inherited FreeInstance;
  end;
end;

class function TSingleton.NewInstance: TObject;
begin
  if (not Assigned(singleton)) then
  begin
    singleton := inherited NewInstance as TSingleton;
  end;
  Result := Singleton;
   Inc(Ref_Count);
end;

end.

### Delphi单例模式的实现方法 在 Delphi 中,单例模式是一种常见的设计模式,用于确保某个类只有一个实存在,并提供全局访问该实的方式。以下是几种典型的实现方式及其解释。 #### 方法一:基于静态变量的经典实现 这种方法利用了一个私有的构造函数以及一个静态变量来存储唯一实。通过这种方式可以有效防止外部直接创建对象。 ```delphi unit uSingleton; interface type TMySingleton = class private constructor Create; // 私有化构造函数 class var FInstance: TMySingleton; public class function GetInstance: TMySingleton; end; implementation { TMySingleton } constructor TMySingleton.Create; begin inherited Create; end; class function TMySingleton.GetInstance: TMySingleton; begin if not Assigned(FInstance) then FInstance := TMySingleton.Create; Result := FInstance; end; end. ``` 上述代码中,`FInstance` 是一个类级别的变量,用来保存唯一的实[^1]。当调用 `GetInstance` 方法时,如果尚未创建实,则会自动初始化;否则返回已存在的实。 --- #### 方法二:线程安全版本 (双重锁定机制) 对于多线程环境下的场景,经典的单例模式可能会引发竞态条件问题。因此可以通过引入同步锁来解决这一问题。 ```delphi unit uThreadSafeSingleton; interface uses SyncObjs; type TThreadSafeSingleton = class private constructor Create; class var FInstance: TThreadSafeSingleton; class var FLock: TCriticalSection; public destructor Destroy; override; class function GetInstance: TThreadSafeSingleton; end; implementation { TThreadSafeSingleton } constructor TThreadSafeSingleton.Create; begin inherited Create; end; destructor TThreadSafeSingleton.Destroy; begin FLock.Free; inherited; end; class function TThreadSafeSingleton.GetInstance: TThreadSafeSingleton; begin if not Assigned(FLock) then FLock := TCriticalSection.Create; FLock.Enter; try if not Assigned(FInstance) then FInstance := TThreadSafeSingleton.Create; finally FLock.Leave; end; Result := FInstance; end; end. ``` 此实现加入了 `TCriticalSection` 来保障多个线程同时请求实时的安全性[^2]。 --- #### 方法三:重写 NewInstance 和 FreeInstance 函数 Delphi 的编译器会对构造函数的保护级别进行特殊处理,即使设置为 `private` 或者 `protected`,仍会被调整为可公开访问的状态。为了避免这种情况发生,可以通过覆盖基类中的 `NewInstance` 和 `FreeInstance` 方法来完全控制对象的生命周期。 ```delphi unit uCustomizedSingleton; interface type TCustomizedSingleton = class private constructor Create; overload; class var FInstance: TCustomizedSingleton; protected class function NewInstance: TObject; override; procedure FreeInstance; override; public class function GetInstance: TCustomizedSingleton; end; implementation { TCustomizedSingleton } constructor TCustomizedSingleton.Create; begin inherited Create; end; class function TCustomizedSingleton.NewInstance: TObject; begin if not Assigned(FInstance) then FInstance := inherited NewInstance as TCustomizedSingleton; Result := FInstance; end; procedure TCustomizedSingleton.FreeInstance; begin // 允许释放实 end; class function TCustomizedSingleton.GetInstance: TCustomizedSingleton; begin if not Assigned(FInstance) then FInstance := TCustomizedSingleton.Create; Result := FInstance; end; end. ``` 这种做法通过对 `NewInstance` 进行自定义逻辑实现了对新对象分配过程的有效干预[^3]。 --- #### 使用示 下面展示如何在一个简的程序中使用这些单例类: ```delphi program SingletonDemo; {$APPTYPE CONSOLE} uses SysUtils, uSingleton in 'uSingleton.pas', uThreadSafeSingleton in 'uThreadSafeSingleton.pas'; var Instance1, Instance2: TMySingleton; ThreadSafeInst1, ThreadSafeInst2: TThreadSafeSingleton; begin Instance1 := TMySingleton.GetInstance; Instance2 := TMySingleton.GetInstance; Writeln('Classic Singleton Instances Equal? ', BoolToStr(Instance1 = Instance2, True)); ThreadSafeInst1 := TThreadSafeSingleton.GetInstance; ThreadSafeInst2 := TThreadSafeSingleton.GetInstance; Writeln('Thread-Safe Singleton Instances Equal? ', BoolToStr(ThreadSafeInst1 = ThreadSafeInst2, True)); Readln; end. ``` 以上代码验证了同类型的是否能够正确返回相同的实[^5]。 --- ### 总结 Delphi 提供了多种灵活的方式来实现单例模式,具体选择取决于实际需求和应用场景。无论是简的需求还是复杂的多线程支持情况,都可以找到合适的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值