//转自http://www.cnblogs.com/MurphyAefe/articles/1741825.html
{
说明:该事例实现的效果,在单个应用或代码量小的项目中,可以完全不用接口委托来完成。
之所以采用委托接口,主要是应用到:已经实现的接口模块中,在不改变原有代码的情况下,
需要对其进行扩展;原始模块只需要开放部分功能,但又不能暴露实现细节的场合;
}
unit TestUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const
TestMsgGUID: TGUID = '{4BE80D5E-D94B-42BE-9114-077DC2708451}';
type
//原始接口中新增需要暴露给其它模块的接口定义,公用部分
ITestMsg = interface
['{4BE80D5E-D94B-42BE-9114-077DC2708451}']
procedure ShowTestMsg;
end;
//---------------------------------服务模块
//基类对象,只需要开放ShowTestMsg方法给外部,所以做为按口的实现基类
TBaseTestMsg = class(TInterfacedObject, ITestMsg)
public
//.... 模块已存在的老代码....
//新开放的接口代码方法
procedure ShowTestMsg; virtual; //申明成虚拟方法,以便继承类可以重载
end;
//---------------------------------接口委托对象定义
TTestMsgClass = class(TInterfacedObject, ITestMsg)
private
FTestMsg: ITestMsg;
public
property Service: ITestMsg read FTestMsg implements ITestMsg;
constructor Create(AClass: TClass);
constructor CreateEx(AClass: TClass); //另一种用法, 不采用TBaseTestMsg做为基类创建委托实例
destructor Destroy; override;
end;
//----------------------------------外部引用的业务模块
//完成具体业务的委托实例
TETestMsg = class(TInterfacedObject, ITestMsg)
public
procedure ShowTestMsg;
end;
//完成具体业务的委托实例
TCTestMsg = class(TInterfacedObject, ITestMsg)
public
procedure ShowTestMsg;
end;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure DoTest(AClass: TClass; ACreateEx: Boolean = False); //测试方法
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TBaseTestMsg }
procedure TBaseTestMsg.ShowTestMsg;
begin
end;
{ TTestMsgClass }
constructor TTestMsgClass.Create(AClass: TClass);
var
vObj: TBaseTestMsg;
begin
vObj := TBaseTestMsg(AClass.NewInstance);
FTestMsg := vObj.Create;
end;
constructor TTestMsgClass.CreateEx(AClass: TClass);
begin
//该方法不采用TBaseTestMsg做为基类创建委托实例,更通用更灵活
(AClass.NewInstance.Create).GetInterface(TestMsgGUID, FTestMsg);
end;
destructor TTestMsgClass.Destroy;
begin
FTestMsg := nil;
inherited;
end;
{ TETestMsg }
procedure TETestMsg.ShowTestMsg;
begin
ShowMessage('TETestMsg Msg:' + 'OK');
end;
{ TCTestMsg }
procedure TCTestMsg.ShowTestMsg;
begin
ShowMessage('TCTestMsg 消息:' + '好的');
end;
//--------------------以下为测试代码--------------------------------
procedure TForm1.DoTest(AClass: TClass; ACreateEx: Boolean);
var
vClass: TTestMsgClass;
vTest: ITestMsg;
begin
if ACreateEx then
vClass := TTestMsgClass.CreateEx(AClass)
else
vClass := TTestMsgClass.Create(AClass);
try
vTest := vClass;
vTest.ShowTestMsg;
finally
vTest := nil;
FreeAndNil(vClass);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DoTest(TETestMsg);
DoTest(TCTestMsg);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
DoTest(TETestMsg, True);
DoTest(TCTestMsg, True);
end;
end.