首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

在Delphi2010里面整了个单例模式,大家看看好用不?该如何处理

2012-02-28 
在Delphi2010里面整了个单例模式,大家看看好用不?Delphi(Pascal) code(* *This unit demonstrates how to

在Delphi2010里面整了个单例模式,大家看看好用不?

Delphi(Pascal) code
(* *  This unit demonstrates how to implement the Singleton Pattern in Delphi 2010. *  The final reversion will be available in the Delphi Spring Framework. *   *  Zuo Baoquan * *)unit SingletonPatternUnit;interfacetype  /// <summary>  /// Provides a simple, fast and thread-safe Singleton Pattern implementation.  /// </summary>  /// <description>  /// Singleton Pattern is defined as:  /// Ensure a class only has one instance, and provide a global point of access to it.  /// </description>  /// <remarks>  /// 1. Use Instance class property to get the singleton instance.  /// 2. Concrete Singleton Classes may override DoCreate/DoDestroy if necessary.  /// 3. Do not call Create/Free methods, otherwise an EInvalidOp exception will be raised.  /// </remarks>  /// <example>  /// <code>  ///   TApplicationContext = class(TSingleton<TApplicationContext>)  ///   protected  ///     procedure DoCreate; override;  ///     procedure DoDestroy; override;  ///   end;  /// </code>  /// </example>  /// <author>Zuo Baoquan (Paul)</author>  TSingleton<T: class> = class //(TInterfaceBase)  strict private    class var fInstance: T;    class function GetInstance: T; static;    class destructor Destroy;  protected    procedure DoCreate; virtual;    procedure DoDestroy; virtual;  public    constructor Create;    destructor Destroy; override;    class property Instance: T read GetInstance;  end;implementationuses  Windows, SysUtils;{$REGION 'TSingleton<T>'}class destructor TSingleton<T>.Destroy;begin  if fInstance <> nil then  begin    TSingleton<T>(fInstance).DoDestroy;    TSingleton<T>(fInstance).FreeInstance;    fInstance := nil;  end;end;constructor TSingleton<T>.Create;begin  raise EInvalidOp.Create('Use Instance class property instead.');end;destructor TSingleton<T>.Destroy;begin  if ExceptObject = nil then    raise EInvalidOp.Create('Free/Destroy.');end;class function TSingleton<T>.GetInstance: T;var  obj: T;begin  if fInstance = nil then  begin    obj := T(T.NewInstance);    TSingleton<T>(obj).DoCreate;    if InterlockedCompareExchangePointer(PPointer(@fInstance)^, PPointer(@obj)^, nil) <> nil then    begin      TSingleton<T>(obj).DoDestroy;      TSingleton<T>(obj).FreeInstance;    end;  end;  Result := fInstance;end;procedure TSingleton<T>.DoCreate;beginend;procedure TSingleton<T>.DoDestroy;beginend;{$ENDREGION}end.



[解决办法]
单例模式是什么?
[解决办法]
至少编译能通过

[解决办法]
没有什么实际用途啊,至少得在类中加一个容器类吧,还要支持多线程安全访问。

而且,你的类最终没法创建实例啊!Create要产生异常;访问Instance更不通,实例都没有被创建,如何能够访问Instance属性喃?形成悖论了。

[解决办法]
先把Create放到protected部分,然后在单元文件中增加initialization和finalization,在这两部分中创建类实例,这样大概可行。


[解决办法]
up,僵哥出声了
[解决办法]
这样比较清晰一些:比如声明一个基类 TBaseSingleton,继承 NewInstance/FreeInstance,让对象不能手动创建和释放对象,而是另外提供 protected 方法负责创建和销毁。提供一个管理类,用一个 class var list 之类维护 TBaseSingleton 的继承类和其实例的对应关系,然后提供一个 class function GetInstance<T: TSingleton>: T 方法,在这里负责创建并考虑线程安全就可以了,就像这样:
Delphi(Pascal) code
  TBaseSingleton  = class abstract  private    class function yourNewInstance: TObject;    procedure yourFreeInstance;  // 别忘了 BeforeDestruction  protected    constructor DoCreate; virtual; abstract; // must be overrided    procedure DoDestroy; virtual;  public    class function NewInstance: TObject; override; // raise an exception    procedure FreeInstance; override; // raise an exception  end;  TSingletonClass = class of TBaseSingleton;  Tfoo = class  private    class var      FDict: TDictionary<TSingletonClass, TBaseSingleton>;      FCS: TRTLCriticalSection;  public    class constructor Create;    class destructor Destroy;    class function GetInstance<T: TBaseSingleton>: T;    {      EnterCriticalSection(FCS);      try        if(FDict.TryGetValue(TSingletonClass(T), TBaseSingleton(Result)))then Exit;        Result  := T(TSingletonClass(T).yourNewInstance);        FDict.Add(TSingletonClass(T), TBaseSingleton(Result));      finally        LeaveCriticalSection(FCS);      end;      TBaseSingleton(Result).DoCreate;    }  end; 


[解决办法]

探讨
引用:
单例是实现了,并且有考虑实例地址的线程安全,但是对于实例的线程安全还是有点欠缺.对于T类型,这里并没有约束不允许调用其Free方法.不清楚D2010当中对于模板类T是否可以约定特定的class.


D2010泛型支持基类约束,比如TPersistentList <T: TPersistent>,不过这个例子有点特殊,T实际上是具体的单例模式子类,如果要写约束的话,得写成TSingleton <T: TSingleton <T>>,但这样不能编译通过。

调用其Free方法,会在Destroy里面抛出异常。

另外请教下僵哥,你说的“对于实例的线程安全还是有点欠缺”是指哪方面?

[解决办法]
up
[解决办法]
up.
[解决办法]
关注中......
[解决办法]
我来看一看
[解决办法]
请问有没有key?谢谢
[解决办法]
我来看看!
[解决办法]
瞅一下……
[解决办法]
分享~ 3q
[解决办法]
Mark!
[解决办法]
学习
[解决办法]
学习一下
[解决办法]
先不要用Delphi2010,因为现在的控件几乎都不支持D2010
[解决办法]
2010开始支持静态变量吗?好像Delphi7没有
[解决办法]
还可以。吧
[解决办法]
单例模式一般都是隐藏构造函数constructor的,LZ应该把构造函数放在protected或者private中,否则就不是严谨的做法了;此外LZ还没有考虑如何保证线程安全的问题了;总的来说,设计思路没什么大的问题,不过基本上也没什么作用,在实际应用中这样的设计基本上没意义!
[解决办法]
这个怎样用了
[解决办法]
这个怎样用了。我不知道
[解决办法]
都是人才啊,为什么我不懂咯
[解决办法]
学习了
[解决办法]
看一懂 UP
[解决办法]
rthrthbrtdhbrjn
[解决办法]
哈哈,很强大。。

[解决办法]
d

热点排行