(接上文)
代碼:
現在把全文的代碼列舉如下,其中有一些上面沒有給出的代碼,但它們也很重要,列在一起方便大家浏覽,請仔細查看下面的代碼以獲得需要的信息,當然本文也僅僅是做為一個簡單的例子,舉出了一些常見的問題和解決技巧,以及象這樣的接口編程的一個可能應用。
接口:
IFoo = interface;<?XML:namespace prefix = o ns = "urn:schemas-microsoft-com:office:Office" />
IFooManager = interface
['{3A10DC39-4B14-4C61-B657-E445C55408B6}']
function CreateAFoo:IFoo;
procedure DelAFoo(id:integer);
function GetFooNum:integer;
function GetFooByID(id:integer):IFoo;
end;
IFoo = interface
//我們要維護的對象,只實現了一個簡單的加法運算做為例子
['{22C541AA-0BA4-4092-B0EB-D267AB1FF001}']
function fooAdd(x,y:integer):integer;
end;
TFoo的聲明和實現:
TFoo = class(TMyInterfacedObject,IFoo)
protected
function fooAdd(x,y:integer):integer;
end;
implementation
{ TFoo }
function TFoo.fooAdd(x, y: integer):integer;
begin
result:=x+y;
end;
工廠類的聲明和實現:
TFooManager=class(TMyInterfacedObject,IFooManager)
private
FList:array of TFoo;
FooNum:integer;
protected
constructor Create;
function CreateAFoo:IFoo;
procedure DelAFoo(id:integer);
function GetFooNum:integer;
function GetFooByID(id:integer):IFoo;
public
destructor Destroy;override;
end;
var
FooMan:TFooManager;
implementation
{ TFooManager }
constructor TFooManager.Create;
begin
FooNum:=0;
end;
function TFooManager.CreateAFoo: IFoo;
begin
inc(FooNum);
if length(FList)<FooNum then
setlength(FList,FooNum*2);
FList[FooNum-1]:=TFoo.Create;
result:=FList[FooNum-1] as IFoo;
end;
procedure TFooManager.DelAFoo(id:integer);
var
i:integer;
begin
if FooNum>0 then
begin
FList[id].Free;
for i:=id to FooNum-2 do
begin
FList[i]:=FList[i+1];
end;
FList[FooNum-1]:=nil;
Dec(FooNum);
end;
end;
destructor TFooManager.Destroy;
//在釋放工廠類前釋放所有所維護的對象
var
i:integer;
begin
for i:=0 to FooNum-1 do
begin
FList[i].Free;
FList[i]:=nil;
end;
Finalize(Flist);
inherited;
end;
function TFooManager.GetFooByID(id: integer): IFoo;
begin
result:=FList[id] as IFoo;
end;
function TFooManager.GetFooNum: integer;
begin
result:=FooNum;
end;
Dll中僅有的兩個導出函數:
function GetFooManIntf:IFooManager;stdcall;
begin
if not assigned(FooMan) then
begin
FooMan:=TFooManager.Create;
end;
result:=FooMan as IFooManager;
end;
procedure FreeLib;stdcall;
//釋放工廠類
begin
if assigned(FooMan) then
begin
FooMan.Free;
FooMan:=nil;
end;
end;