[转]解耦:Delphi下IoC 模式的实现

解耦:Delphi下IoC 模式的实现

摘要:在Delphi下IoC模式的多种实现

Ioc英文为 Inversion of Control,即反转模式,这里有著名的好莱坞理论:你呆着别动,到时我会找你。Ioc模式是解决调用者和被调用者之间关系的模式,可以有效降低软件的耦合度,并适合团队开发,使用这种模式需要首先设计一个好的框架,也可以称之为IoC容器

(可能这样的说法在Java世界更Cool J)。其实Windows内部就存在这样的模式,称之为

Callback(回调),在Delphi 的源代码中也有很多这样的方式。看一个例子:

       可以打开下面两个文件

       $(Delphi)\Source\Vcl\DB.pas

       $(Delphi)\Source\Vcl\DBLogDlg.pas

       第二个文件是一个需要用户填写登录用户名和密码的对话框,显然这属于用户交互层,

我们不希望在DB.pas(数据逻辑层)中直接调用这个功能,Delphi是这样实现的:

       DB.pas #2282 有这样的声明:

  LoginDialogProc: function (const ADatabaseName: string; var AUserName, APassword: string): Boolean;

       LoginDialogProc 被定义为函数类型变量。

       在DBLogDlg.pas #132

initialization

  if not Assigned(LoginDialogProc) then

    LoginDialogProc := LoginDialog;

       也就是在DBLogDlg.pas单元初始化阶段给DB.Pas中的LoginDialogProc赋予实现函数。

我觉得这个例子已经足够把问题说得清楚了。

当然这并非实现IoC的唯一方法,对于不同的语言都有自己的特性,上面的方法可能比较古老的一种,通过函数指针来实现,其他的方法还有

    一:封装为接口

              我们看到在DB.pas 中声明了很多类似的函数变量,我们可以将其封装为一个接口

       IDBDlogInterface = Interface

  ['{06B5DEAC-0BB1-4658-91F6-E78004DF131D}']

  LoginDialogProc: function (const ADatabaseName: string; var AUserName, APassword: string): Boolean;

  LoginDialogExProc: function (const ADatabaseName: string; var AUserName, APassword: string; NameReadOnly: Boolean): Boolean;

  RemoteLoginDialogProc: function (var AUserName, APassword: string): Boolean;

end;

然后申明一个全局的接口类型变量

Var

       DBDialog : IDBDialogInterface ;

       然后在其他单元实现这个接口,并初始化时赋值到这个接口变量。

       二:注册机制的IoC

       这个例子稍微复杂一些,但是似乎更实用

       我们在一个窗口上放置了一个pageControl,我们知道一个pageControl上可以放置多个pageControl,而且这多个 pageControl功能相对独立,没有耦合。我们可以这样做:建立这个主窗体放置一个空的PageControl,然后声明一个 TInterfaceList变量用来存储PageControl的具体实现。每一个PageControl动态创建,使用注册的Frame来填充

       代码如下:

unit frmStartPage;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs,  StdCtrls, ImgList,Contnrs, ComCtrls, ExtCtrls;

Type

  //填充pageControl的Frame基类

  TPageFrame = class(TFrame)

  protected

    function Caption :String ; virtual; abstract;

  end;

  TPageFrameClass = class of TPageFrame ;

  TStartPage = class(TForm)

    PageControl1: TPageControl;

    procedure FormCreate(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;

var

  StartPage :TStartPage ;

  RegTabSheetClasses: TClassList;

  procedure RegisterStartPageTabSheet( AFrameClass :TPageFrameClass);

implementation

{$R *.dfm}

procedure TStartPage.FormCreate(Sender: TObject);

var

  i:integer;

  lTabSheet : TTabSheet;

  lFrame : TPageFrame;

begin

  for i:= 0 to RegTabSheetClasses.Count -1 do

  begin

    lTabSheet := TTabSheet.Create(PageControl1);

    lFrame := TPageFrameClass( RegTabSheetClasses[i]).Create(self) as TPageFrame;

    lTabSheet.Caption := lFrame.Caption ;

    lFrame.Align := alClient;

    lTabSheet.InsertControl(lFrame);

    lTabSheet.PageControl := PageControl1;

    lTabSheet.PageIndex := 0 ;

  end;

end;

procedure RegisterStartPageTabSheet( AFrameClass :TPageFrameClass);

begin

  RegTabSheetClasses.Add(AFrameClass);

end;

initialization

  RegTabSheetClasses := TClassList.Create ;

finalization

  RegTabSheetClasses.Free;

end.

unit Unit2;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs,frmStartPage, StdCtrls;

type

  TFrame2 = class(TPageFrame)

    Label1: TLabel;

  private

    { Private declarations }

  protected

    { Public declarations }

    function Caption :String ; override;

  public

  end;

implementation

{$R *.dfm}

{ TFrame2 }

function TFrame2.Caption: String;

begin

  result := 'Frame1';

end;

initialization

  RegisterStartPageTabSheet(TFrame2);

end.

转载于:https://www.cnblogs.com/moon25/archive/2009/11/11/1600879.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elite Container是DELPHI下的一个轻量级IoC对象容器(IoC:Inverse of Control,反控制)。它是参考了Java中的Spring框架(主要是配置文件的写法),并结合DELPHI的特点来构建的。相比Spring的对象容器,它提供的功能更为精简常用(如对象延迟创建、对象属性自动注入等),降低了学习的难度,并且提供了很多扩展点,你只需简单地写一个插件实现类,并在配置文件中进行简单配置,就可以让Elite Container拥有你的自定义功能! 借助Elite Container和Ioc思想,你可以更轻易地构建出具有松散耦合、重用度高的应用程序。它的核心思想就是拆分功能的接口和实现,上层只依赖于下层的接口,然后通过Elite Container的配置,把不同的实现类注入到该接口中,达到更换功能,也就是复用已有代码的目的。设计人员可以真正地发挥好自己的面向对象思想和相关设计模式,来架构企业级的应用程序,而无需象以前那样,在Delphi中用起面向对象总有点捉襟见袖的感觉。 ps. 由于写程序,还有精心准备的26个例子,都花费了我很多的时间,所以象征性地收2个资源分,希望大家不会介意:) ps2. 说明一下,开发出来的程序在发布的时候,除了发布EliteCore.bpl、EliteContainer.bpl外,还需要发布rtl.bpl(EliteCore.bpl引用到了它)。由于一时疏忽,例子中的Bin目录里忘记带上它了,请大家注意,谢谢~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值