打印本文 打印本文 关闭窗口 关闭窗口
使用类方法控制实例的唯一性
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1302  更新时间:2009/4/23 18:26:29  文章录入:mintao  责任编辑:mintao

使用类方法控制实例的唯一性

CST 2005-7-29

 

文档目的

在面向对象编程中,出于各种原因,有时我们希望控制一个类的实例仅有一个存在于内存中。例如我在编程中遇到一个实际情况,程序的配置数据保存在XML文档中,需要写一个XML配置文件解析类。由于读入的数据可能很庞大,而且在程序每个模块中都用到该解析类的实例,那么如果每次都创建一个实例并重新读入数据,效率就不令人满意了。

 

 

类方法

我们可以通过类方法(Class Method)实现实例创建的控制,其实也有许多其他的方法。这里我先介绍“类方法”的实现。

 

如下是DELPHI对类方法的定义:

A class method is a method (other than a constructor) that operates on classes instead of objects. The definition of a class method must begin with the reserved word class. For example,

 

type

  TFigure = class

  public

    class function Supports(Operation: string): Boolean; virtual;

    class procedure GetInfo(var Info: TFigureInfo); virtual;

    ...

  end;

 

The defining declaration of a class method must also begin with class. For example,

 

class procedure TFigure.GetInfo(var Info: TFigureInfo);

begin

  ...

end;

 

In the defining declaration of a class method, the identifier Self represents the class where the method is called (which could be a descendant of the class in which it is defined). If the method is called in the class C, then Self is of the type class of C. Thus you cannot use Self to access fields, properties, and normal (object) methods, but you can use it to call constructors and other class methods.

A class method can be called through a class reference or an object reference. When it is called through an object reference, the class of the object becomes the value of Self.

 

定义一个类方法就是在将一个方法生命在PUBLIC段中,并加上class前缀。这样的方法可以由类直接调用,而不需要先创建类的实例。比如构造函数Create就是一个类方法,我们在创建对象实例的时候这样写:

MyObject:=TmyClass.Create;

此时的Create方法由类TmyClass调用。

 

实现方法

我们实现的目的就是不以平时的对象访问模式调用对象

Myobject:=TmyClass.Create(self);

Try

  With Myobject do begin

//do something

  end;

finally

  FreeAndNil(Myobject);

End;

 

而是使用一个类方法GetInstance来间接获取对象实例,这个唯一的对象实例被申明在类的单元文件内(后文回详细说明),在GetInstance函数中判断该实例是否被创建赋值,如果没有,则调用构造函数创建;如果已创建,则直接返回该实例。

这里,我们需要将构造函数Create申明在private段中,仅能由GetInstance判断调用。TmyClass.GetInstance函数返回值为TmyClass类型的变量,如果Tmyclass继承自Tcomponent的话,create方法需要一个Aowner参数,因此我为GetInstance增加一个Aowner参数。

 

GetInstance类方法的实现不影响类中其他方法的实现,一般我们在调试设计阶段不进行类方法的考虑,而是公开需要测试的对象方法以便于调试。最后要发布类的时候,我们做如下改动:

1.        在类单元文件中,但是在类定义之外申明唯一对象变量。
我的做法是在
implementation
var mySoloObject:TMyClass;

2.        隐藏构造函数
将constructor函数申明在private段中

3.        增加一个GetInstance类方法,定义在Public段中,判断mySoloObject是否被创建。

 

具体代码如下:

……

//类定义

TConfigReader = class(TComponent)

        private

            FXMLDoc: TXMLDocument;       

            constructor Create(AOwner:TComponent); override;

        public

            FCtrlInfoList:TObjectList;

            function OpenXMLFile(const APath:string):boolean;

            function ReadCtrlInfoToList: Integer;

            class function GetInstance(AOwner:TComponent):TConfigReader;

        end;

//唯一对象变量

 

implementation

 

var

ConfigReaderSolo:TConfigReader;

 

//函数定义

class function TConfigReader.GetInstance(AOwner:TComponent):TConfigReader;

begin

    if ConfigReaderSolo=nil then

       ConfigReaderSolo:=TConfigReader.Create(AOwner);

    Result:=ConfigReaderSolo;

[1] [2]  下一页

打印本文 打印本文 关闭窗口 关闭窗口