在今后的 Delphi 中, 以接口、结构为主的设计应该会越来越多, 因为这样太方便了.
System.RegularExpressions 就是以结构为主体设计的非常好的示范; 但更多东西使用接口会更合适.
有见过他人早就使用接口写程序, 从手头的这个程序开始我才开始使用.
现在基本总结出四种框架模式: 1、直接实现; 2、间接实现(或叫继承实现); 3、覆盖实现; 4、委托实现.
一、直接实现:
下例中虽有 TMy1、TMy2, 但在具体应用中使用的应是 IMy1、IMy2, 这就是我所谓的以接口为主导.
TMy1、TMy2 直接实现了所属接口的所有方法, 这是我所谓的直接实现.
这样可能会有代码重复, 但如果程序很小, 还是挺实用的.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;
IA = Interface
procedure Method_A;
end;
IB = Interface(IA)
procedure Method_B;
end;
IMy1 = Interface(IB)
procedure Method_My1;
end;
IMy2 = Interface(IB)
procedure Method_My2;
end;
TMy1 = class(TInterfacedObject, IMy1)
procedure Method_A;
procedure Method_B;
procedure Method_My1;
end;
TMy2 = class(TInterfacedObject, IMy2)
procedure Method_A;
procedure Method_B;
procedure Method_My2;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TMy1 }
procedure TMy1.Method_A;
begin
ShowMessage('A');
end;
procedure TMy1.Method_B;
begin
ShowMessage('B');
end;
procedure TMy1.Method_My1;
begin
ShowMessage('My1');
end;
{ TMy2 }
procedure TMy2.Method_A;
begin
ShowMessage('A');
end;
procedure TMy2.Method_B;
begin
ShowMessage('B');
end;
procedure TMy2.Method_My2;
begin
ShowMessage('My2');
end;
{测试}
procedure TForm1.FormCreate(Sender: TObject);
var
v1: IMy1;
v2: IMy2;
begin
v1 := TMy1.Create;
v1.Method_A;
v1.Method_B;
v1.Method_My1;
v2 := TMy2.Create;
v2.Method_A;
v2.Method_B;
v2.Method_My2;
end;
end.
二、间接实现:
下面例子通过一个间接的 TB 类, 避免了 TMy1、TMy2 中可能会重复的代码.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;
IA = Interface
procedure Method_A;
end;
IB = Interface(IA)
procedure Method_B;
end;
TB = class(TInterfacedObject, IB)
procedure Method_A;
procedure Method_B;
end;
IMy1 = Interface(IB)
procedure Method_My1;
end;
IMy2 = Interface(IB)
procedure Method_My2;
end;
TMy1 = class(TB, IMy1)
procedure Method_My1;
end;
TMy2 = class(TB, IMy2)
procedure Method_My2;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TB }
procedure TB.Method_A;
begin
ShowMessage('A');
end;
procedure TB.Method_B;
begin
ShowMessage('B');
end;
{ TMy1 }
procedure TMy1.Method_My1;
begin
ShowMessage('My1');
end;
{ TMy2 }
procedure TMy2.Method_My2;
begin
ShowMessage('My2');
end;
{测试}
procedure TForm1.FormCreate(Sender: TObject);
var
v1: IMy1;
v2: IMy2;
begin
v1 := TMy1.Create;
v1.Method_A;
v1.Method_B;
v1.Method_My1;
v2 := TMy2.Create;
v2.Method_A;
v2.Method_B;
v2.Method_My2;
end;
end.
三、覆盖实现:
从 TB 继承的过程中当然也可以通过覆盖虚函数而实现多态, 下面的 TMy2 就这么做了.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;
IA = Interface
procedure Method_A;
end;
IB = Interface(IA)
procedure Method_B;
end;
TB = class(TInterfacedObject, IB)
procedure Method_A; virtual;
procedure Method_B; virtual;
end;
IMy1 = Interface(IB)
procedure Method_My1;
end;
IMy2 = Interface(IB)
procedure Method_My2;
end;
TMy1 = class(TB, IMy1)
procedure Method_My1;
end;
TMy2 = class(TB, IMy2)
procedure Method_A; override;
procedure Method_B; override;
procedure Method_My2;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TB }
procedure TB.Method_A;
begin
ShowMessage('A');
end;
procedure TB.Method_B;
begin
ShowMessage('B');
end;
{ TMy1 }
procedure TMy1.Method_My1;
begin
ShowMessage('My1');
end;
{ TMy2 }
procedure TMy2.Method_A;
begin
ShowMessage('A_My2');
end;
procedure TMy2.Method_B;
begin
ShowMessage('B_My2');
end;
procedure TMy2.Method_My2;
begin
ShowMessage('My2');
end;
{测试}
procedure TForm1.FormCreate(Sender: TObject);
var
v1: IMy1;
v2: IMy2;
begin
v1 := TMy1.Create;
v1.Method_A;
v1.Method_B;
v1.Method_My1;
v2 := TMy2.Create;
v2.Method_A;
v2.Method_B;
v2.Method_My2;
end;
end.
四、委托实现:
接口中的方法是肯定要实现的, 但也可以通过 implements 关键字借用(或叫委托)其它的实现;
但, 官方文档说这只适用于 Win32. 就是说这种方法在 Win64 和其它系统都不行, 还学它干嘛?
浙公网安备 33010602011771号