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.

转至:http://tb.blog.csdn.net/

http://www.cnblogs.com/sonicit/archive/2008/04/08/1141831.html

最新文章

  1. opencv 人脸识别
  2. 基础才是重中之重~ConcurrentDictionary让你的多线程代码更优美
  3. unity 解析tmx
  4. tkinter 改变按钮状态
  5. 常用Linux命令小结
  6. sqlserver 大文件脚本执行
  7. ThinkPHP表单令牌验证功能详细介绍
  8. android UI进阶之弹窗的使用(2)--实现通讯录的弹窗效果
  9. LR设置关联---部分内容摘自网络--望见谅
  10. java笔记04: String的理解与运用
  11. ip001
  12. 11招玩转黑客攻防——用Python,更安全
  13. TortoiseGit拉取或推送,输入账号密码后提示 HTTP Basic: Access denied fatal: Authentication failed 解决方案
  14. easyui 单元格超出鼠标放上弹出全部
  15. Git&GitHub-进阶教程
  16. JVM的基本结构及其各部分详解(二)
  17. echarts 折线统计笔记
  18. javascript获取style兼容性问题
  19. GoldenGate实时投递数据到大数据平台(4)- ElasticSearch 2.x
  20. 第六节 Go数据结构之集合

热门文章

  1. CSS布局--左侧自适应母元素高度
  2. UVA 1428 - Ping pong(树状数组)
  3. C#高效率复制对象
  4. WPF 渲染级别
  5. URAL 1684. Jack's Last Word KMP
  6. Redis中的管道(PipeLine)与事物(Transactions)
  7. DB 查询分析器 轻松创建DB2定义他们自己的函数
  8. 给WPF文字加多条修饰线
  9. Editplus配置Python的开发环境
  10. 简明Python3教程 2.序言