亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Delphi > 正文

兩種Delphi實現Singleton模式方法

2019-11-18 18:39:16
字體:
來源:轉載
供稿:網友
 

兩種Delphi實現Singleton模式方法

haozi


摘  要 本文描述了兩種Singleton模式的Delphi實現方式,并做了對比分析。
關鍵字 設計模式,Singleton

Singleton(單件)模式是一種很有用的設計模式。它的意圖的是:僅僅創建一個類的實例,并提供一個訪問它的全局訪問點。全局變量使的一個對象易被訪問,但不能防止你實例化多個對象。單件模式的目的就是確保在程序的生命周期內只有一個實例存在。
看下面的代碼:
PRocedure TForm1. Button1Click(Sender: TObject);
var  lS1 : TSingleton;  l
S2 : TSingleton;
begin
  try    lS1 := TSingleton.Create;   ////調用類的構造器   
    lS2 := TSingleton.Create;   ////調用類的構造器 
    //// ...別的代碼 
  finally
    lS1.Free;  ////釋放對象
    lS2.Free;  ////釋放對象
  end;
end;

在上面的代碼中第一次調用Create函數時TSingleton類被實例化,lS1指向一個內存存放對象的地址,當第二次調用TSingleton.Create函數時又重新實例化了TSingleton對象,lS2指向內存分配的另一個地址。Singleton模式就是讓類自己負責保存他的唯一實例。

在上面的代碼中就是讓lS2創建的時候也指向lS1指向的對象(也就是被分配同一個內存地址),同樣我們在釋放lS1時必須防止內存被釋放,因為單件對象還被lS2所引用。從而保證在程序的生命周期內有且只有一個類實例。
 《設計模式》C++的示例代碼是使用C++的靜態成員變量保存實例的,同時使用protected的構造器函數。但是在Delphi中由于沒有靜態成員變量,所以不能原樣的使用該單件模式示例的方法。以下我們分析兩種DELPHI實現Singleton模式的幾種方法。

一.基于override兩個Tobject虛擬函數的方法

class function NewInstance: TObject; virtual;
procedure FreeInstance; virtual;
NewInstance函數負責類對象創建的時候為對象分配內存,FreeInstance則相反釋放內存

。
前者在對象構造時調用,后者在對象析構時調用。
我們使用兩個全局變量來保存單件對象和對象的引用記數。
var  Instance  : TSingleton  = nil;
     RefCount : Integer     = 0;

TSingleton類的單元:
////---------------------------------------------------------------------------

////
unit uSingleton;

interface

type
  TSingleton = class(TObject)
  public
    class function NewInstance: TObject; override; ////覆蓋基類函數
    procedure FreeInstance; override;              ////覆蓋基類函數
    class function RefCount: Integer; ////返回當前引用記數
  end;

//// Declaration global variables
var
  Instance: TSingleton = nil;
  RefCount: Integer = 0;

implementation

{ TSingleton }

procedure TSingleton.FreeInstance;
begin
  Dec( RefCount );   ////減少引用記數
  if ( RefCount = 0 ) then  ////是否為0,是則釋放內存
  begin
    Instance := nil;
//// 釋放單件類的私有變量
////…
    inherited FreeInstance;
  end;
end;

class function TSingleton.NewInstance: TObject;
begin
  if ( not Assigned( Instance ) ) then
  begin
    Instance := TSingleton(inherited NewInstance);
    ////初始化私有變量 例子:
    ////   Instance.VariableName := Value;
  end;
  Result := Instance ;
  Inc( RefCount );
end;

class function TSingleton.RefCount: Integer;
begin
  Result := RefCount;
end;

end.
////---------------------------------------------------------------------------

////


當調用TSingleton的構造器的時候,會調用我們override的NewInstance函數,由NewInstance分配內存并返回給構造器,這樣通過override的NewInstance函數我們確保了Create函數只可能實例化一個TSingleton對象(無論調用多少次Create只返回第一次分配的內存地址)。同時RefCount變量保存我們有幾個到對象的引用。

我們在來看測試代碼

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(IntToStr(RefCount)); //// Ref_Count = 2
  Ob1 := TObject.Create;
  Ob2 := Tobject.Create;
  if lS1 = lS2 then
    ShowMessage('地址相等') //// lS1 = lS2
  else
    ShowMessage('地址不相等');
  if Ob1 = Ob2 then
    ShowMessage('地址相等')
  else
    ShowMessage('地址不相等'); //// Ob1 <> Ob2
end;
當程序調用析構器的時候(就是調用FREE函數的時候),析構器會調用FreeInstance函數釋放被構造器分配的內存。Override的FreeInstance函數保證引用記數為零的時候才釋放單件模式對象的內存。
下面是我們的測試代碼:
var
  lS1 : TSingleton;
  lS2 : TSingleton;
begin
 try
    lS1 := TSingleton.Create;   ////調用類的構造器
    lS2 := TSingleton.Create;   ////調用類的構造器
  //// ...別的代碼
  finally
    lS1.Free;  ////這里會首先調用我們覆蓋定義的FreeInstance,
              ////由于這時RefCount在減1后為1,單件對象沒有被釋放
    lS2.Free;  ////dec(RefCount)= 0 釋放單件對象
  end;
end;

上面這種單件模式實現方法很好地實現了由類自身來負責保存自己的唯一實例(通過截取創建新對象的請求——參考《設計模式》。它對TSingleton類的使用沒有特殊的限制——程序員可以隨意的調用Create和Free函數。
本模式的缺點是:該TSingleton類不能作為父類繼承生成子類。如果繼承生成兩個子類,Create時只產生一個對象。
procedure TForm1.Button1Click(Sender: TObject);
var
  lS1 : 子類一;
  lS2: 子類二;
begin
  lS1 := 子類一.Create;
  lS2 := 子類二.Create;  ////不會創建子類二,lS2將指向lS1指向的內存,
                        ////也就是  lS1 = lS2end;

二.《設計模式》上示例的Delphi實現
 《設計模式》的實現示例是通過私有構造器函數來實現控制只產生一個對象實例。但該給出的C++代碼實現未給出對象如何釋放。Delphi里面不能實現Create函數的私有化,我們新定義一個函數來代替Create函數,同時屏蔽父類的Create函數。代碼如下


////---------------------------------------------------------------------------

////
unit uSingletonUnit;

interface
uses
  Classes, SysUtils;
type

  TCSingleton = class(TComponent)  ////從Tcomponent類繼承來。
  private
constructor CreateInstance(AOwner: TComponent); ////傳遞Owner參數
//// 這樣TCSingleton類對象就會隨Owner一起銷毀(擁有者負責銷毀TCSingleton對象)
  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
////屏蔽Create函數的功能
  raise Exception.CreateFmt('access class %s through Instance only',
    [ClassName]);
end;

constructor TCSingleton.CreateInstance(AOwner: TComponent);
begin
  ////新定義的構造函數Private型的
  inherited Create(AOwner);
end;

class function TCSingleton.Instance(AOwner: TComponent): TCSingleton;
begin
  if not Assigned(gCSingleton) then
    gCSingleton := TCSingleton.CreateInstance(AOwner);
  Result := gCSingleton;
end;

end.
////--------------------------------------------------------------------------/

/
上面的實現類使用過程中,程序員不用考慮單件模式對象的銷毀問題。只是不能調用Create,必須調用Instance函數來獲得對象的實例,同時把單件擁有者作為參數傳遞到函數里。這種實現方法可以作為基類被繼承,用在狀態模式的單件里(參見參考文獻4),實現執行時的多態。
三.結束語

Singleton 模式的Delphi實現在網上還能查著其他的一些實現方式,本文的兩種方法上

最常見的和簡單的。同時其它方法的思路也很跟以上兩方法很相似。


上一篇:SGIP的delphi原碼

下一篇:Delphi中關于TApplication類的詳解

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品视频免费观看www| 这里只有精品在线播放| 曰本色欧美视频在线| 日韩电影免费在线观看中文字幕| 精品女同一区二区三区在线播放| 久久男人av资源网站| 久久精品亚洲精品| 国产日产亚洲精品| 青草热久免费精品视频| 色综合色综合网色综合| 2020国产精品视频| 黄色成人在线播放| 日韩最新在线视频| 在线国产精品视频| 精品国产精品三级精品av网址| 中文字幕欧美国内| 日韩美女福利视频| 久久99视频免费| 欧美性猛交视频| 欧美激情在线狂野欧美精品| 欧美成人免费一级人片100| 亚洲精品xxxx| 欧美一级黑人aaaaaaa做受| 国产亚洲精品久久久久久| 日韩av免费观影| 色婷婷综合久久久久中文字幕1| 日韩中文字幕网| 57pao精品| 在线播放精品一区二区三区| 国产精品视频久久久久| 欧美午夜影院在线视频| 大胆欧美人体视频| 欧美成年人视频网站欧美| 91中文字幕在线观看| 国产精品极品在线| 欧美性生交大片免费| 国产精品吹潮在线观看| 久久久久久综合网天天| 国产日韩欧美在线观看| 欧美激情亚洲综合一区| 日日狠狠久久偷偷四色综合免费| 日韩av片电影专区| 亚洲欧美激情四射在线日| 中文字幕一区电影| 欧美视频裸体精品| 中文字幕亚洲综合久久筱田步美| 欧美黑人巨大xxx极品| 亚洲小视频在线观看| 2021国产精品视频| 亚洲欧美日韩直播| 亚洲综合小说区| 欧美交受高潮1| 精品亚洲一区二区三区| 亚洲精品国产精品国自产在线| 精品国产31久久久久久| 国产精品网站大全| 国产精品国产自产拍高清av水多| 成人在线视频网| 国产不卡一区二区在线播放| 91免费在线视频网站| 国产精品美女呻吟| 亚洲最大福利视频| 91精品久久久久久久| 国产免费一区视频观看免费| 亚洲精品一区在线观看香蕉| 欧美一区二三区| 国产一区二区三区直播精品电影| 欧美色另类天堂2015| 国产精品视频中文字幕91| 福利视频导航一区| 日韩精品中文字幕在线| 国产在线观看精品一区二区三区| 亚洲激情在线视频| 97精品伊人久久久大香线蕉| 亚洲欧美日韩视频一区| 欧美激情网站在线观看| 在线播放国产一区中文字幕剧情欧美| 日韩美女毛茸茸| 亚洲色图第一页| 久久久精品视频成人| 精品国产欧美成人夜夜嗨| 亚洲aaa激情| 欧美激情国内偷拍| 国产日韩av高清| 亚洲欧美日韩一区二区在线| 国产不卡av在线| 中文字幕日韩在线观看| 欧美日韩成人在线观看| 国产亚洲精品久久久久久777| 亚洲石原莉奈一区二区在线观看| 亚洲品质视频自拍网| 久久精品国产亚洲7777| 亚洲欧美日韩图片| 国产精品三级美女白浆呻吟| 亚洲天堂久久av| 亚洲电影免费观看高清完整版在线观看| 国产精品激情自拍| 欧美麻豆久久久久久中文| 国产一区二区在线免费视频| 成人在线国产精品| 国产精品午夜国产小视频| 久久躁日日躁aaaaxxxx| 日韩欧美在线视频| 国产精品久久久久久久美男| 97精品一区二区视频在线观看| 欧美亚洲国产视频小说| 亚洲欧美另类在线观看| 成人美女av在线直播| 亚洲xxx自由成熟| 国产日韩欧美综合| 欧美日韩中文在线观看| 国产亚洲精品一区二区| 欧美日韩国产一区二区三区| 97视频在线观看播放| 国产一区二区精品丝袜| 77777亚洲午夜久久多人| 91色精品视频在线| 成人国产精品久久久久久亚洲| 亚洲天堂一区二区三区| 欧美亚洲一区在线| 欧美日韩精品在线观看| 欧美成年人视频网站欧美| www.亚洲男人天堂| 精品人伦一区二区三区蜜桃免费| 欧美日韩成人免费| 91成人免费观看网站| 久久精品成人欧美大片古装| 国产精品男人爽免费视频1| 亚洲国产欧美一区二区三区同亚洲| 欧美日韩福利在线观看| 国外成人在线直播| 欧美视频在线视频| 日韩中文字幕在线| 91久久久精品| 国产精品扒开腿做| 在线免费看av不卡| 亚洲精品日韩欧美| 538国产精品视频一区二区| 亚洲香蕉在线观看| 亚洲老头同性xxxxx| 日本乱人伦a精品| 欧美在线观看www| 久久久国产精品一区| 国内免费久久久久久久久久久| 国产日韩欧美在线观看| 久久精品国产成人| 亚洲精品一区久久久久久| 欧美性猛交xxxx富婆弯腰| 黑人巨大精品欧美一区二区| 日本在线观看天堂男亚洲| 亚洲欧洲日产国产网站| 欧美激情视频在线免费观看 欧美视频免费一| 久久亚洲精品网站| 国产成人精品a视频一区www| 最近更新的2019中文字幕| 91色精品视频在线| 精品亚洲男同gayvideo网站| 久久久国产视频| 国产精品久久久久av| 日韩电视剧在线观看免费网站| 欧美性色视频在线| 黄色一区二区在线观看| 久久97精品久久久久久久不卡| 国产精品偷伦视频免费观看国产|