文档章节

以接口为主导的设计中, 我在使用的框架模式

涂孟超
 涂孟超
发布于 2014/09/26 15:33
字数 826
阅读 7
收藏 0

在今后的 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 和其它系统都不行, 还学它干嘛?

本文转载自:http://www.cnblogs.com/del/archive/2012/01/03/2311077.html

涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
私信 提问
JAVA学习笔记(6)_____Java 策略模式 Strategy Pattern

策略模式Strategy Pattern   在Java的集合框架中,经常需要通过构造方法传入一个比较器Comparator,或者创建比较器传入Collections的静态方法中作为方法参数,进行比较排序等,使用的是策略...

sky丶novak
2014/07/30
0
0
Java中的泛型(二)

泛型可以应用于同一个类,该类可以针对多种类型使用,例如构建一个RedisTemplateService组件,用于处理当前应用中所有对象的缓存操作。这篇文章主要介绍泛型应用于接口、方法和匿名内部类的一...

阿杜
2017/12/09
0
0
写书计划《让我们一起开源吧》目录大纲

目标读者: 写框架的人或者正在计划写框架的人,个人开源项目爱好者,有想法参与开源项目的读者。读者范围还可以扩大到Java初学者。 本书特色: 本书的视角是通过个人作者发起开源项目为切入...

哈库纳
2016/11/24
482
26
1 Spring核心:IoC容器的实现

依赖控制反转的实现有很多种方式。在Spring中,IoC容器是实现这个模式的载体, 它可以在对象生成或初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中的方式来注入对方...

qq_18150351
2018/04/24
0
0
Java泛型基础(二)

本文首发于个人网站:Java中的泛型(二) 泛型可以应用于同一个类,该类可以针对多种类型使用,例如构建一个RedisTemplateService组件,用于处理当前应用中所有对象的缓存操作。这篇文章主要...

杜琪
2017/12/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

前端面试题汇总

一. HTML常见的兼容性 1.HTML5 标签在低版本浏览器不兼容 解决办法:使用html5shiv库,引入下列语句 <!--[if lte IE 8]> <script src="https://cdn.bootcss.com/html5shiv/r29/html5.js"></sc......

蓝小驴
17分钟前
3
0
OSChina 周四乱弹 —— 我气的脸都黑了!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐《Red Battle》- 高橋李依 / 豊崎愛生 《Red Battle》- 高橋李依 / 豊崎愛生 手机党少年们想听歌,请使劲儿戳(这里) @丶Lion ...

小小编辑
30分钟前
370
18
找OSG教程, B站就有

https://www.bilibili.com/video/av64849038?from=search&seid=11632913960900279653

洛克人杰洛
52分钟前
4
0
学习记录(day07-Vue组件、自定义属性、自定义事件)

[TOC] 1.1.1什么是组件 一个vue文件就是一个组件 组件将html标签/css样式/对应JS打包成一个整体,也可以理解钻进一个具有样式和特效的自定义标签。 一、编写组件(提供方)<template> <di...

庭前云落
57分钟前
4
0
使用Prometheus监控SpringBoot应用

通过之前的文章我们使用Prometheus监控了应用服务器node_exporter,数据库mysqld_exporter,今天我们来监控一下你的应用。(本文以SpringBoot 2.1.9.RELEASE 作为监控目标) 编码 添加依赖 使...

JAVA日知录
58分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部