利用VFI提高Delphi程序的重用性
摘要:程序重用性是软件质量的重要指标之一,提高重用性对于减少程序潜在缺陷,提高程序开发效率,降低维护成本具有重要的影响。本文针对Delphi所提供的VFI,给出了具体应用VFI来提高程序重用性的实例。该实例表明,使用VFI可以极大地简化程序代码,并保持界面的一致性,提高程序开发效率。
关键词:重用性、Delphi、VFI
1 引言
软件重用(Software Reuse)已经深入人心,早在1968年的NATO软件工程会议上就已经提出可复用库的思想。软件重用,又称软件复用或软件再用,它的定义也很多,比较权威和通用的一种是:软件重用是利用事先建立好的软件部产品创建新软件系统的过程。这个定义蕴含着软件重用所必须包含的两个方面:
1.系统地开发可重用的软件部产品。这些软部品可以是代码,但不应该仅仅局限在代码,还可以是分析,设计,测试数据,原型,计划,文档,模板,框架等等。
2.系统地使用这些软部品作为构筑模块,来建立新的系统。
软件重用可以带来很多好处,如提高软件生成率,缩短开发周期,降低软件开发和维护费用,生产更加标准化的软件,提高软件开发质量,增强软件系统的互操作性等。
在面向对象技术成为当今软件开发的主流技术的今天,软件复用更是提高到了一个重要的位置。复用性是面向对象的一个目标,同时,从另一方面来说,面向对象技术为软件复用提供了更好的手段。它将软件复用的层次从常见的源代码复用、库函数复用等较为低层次的复用提高到类的复用,构件的复用,以至于是架构、框架的复用。
2 Delphi中的VFI
Delphi作为一种支持面向对象的开发工具,采用Object Pascal作为其语言,并提供了可视化的开发环境,极大地提高了软件开发的效率。
与常见的RAD工具(如Visual Basic、C++ Builder和Power Builder等)相同,Delphi提供了窗体设计器。而Delphi的窗体设计器的与众不同之处在于,Delphi是建立在一个真正面向对象的框架结构基础之上的,对基类所做的改变都将会传递给所有的派生类,它所采用的关键技术就是VFI(Visual Form Inheritance),即可视化窗体继承。VFI技术使开发人员能够动态地继承当前项目或对象库中的任何其他窗体,一旦基窗体发生改变,派生的窗体会立即更新。
窗体继承早在Delphi 5中就成为一个内置功能。要基于一个已有的窗体创建一个新的窗体,只要使用File | New菜单命令,Delphi将打开New Items对话框。这个对话框列出了对象库中的所有对象。翻到Forms页,这里列出了所有已经加到对象库中的窗体;也可以选择Project页,来选择一个本项目中已有的窗体。
有三个选项用于把窗体加到项目中:Copy、Inherit和Use。如果选择Copy,则意味着把所选窗体的副本加到当前项目中。如果对象库中的窗体发生变化,不会影响到当前项目中的副本。如果选择Inherit,则意味着从所选窗体派生出一个新的窗体加到当前项目中。如果对象库中的窗体发生变化,则派生的窗体也会跟着变化。如果选择Use,则意味着所选的窗体直接加到当前项目中,就好像这个窗体是当前项目创建的一样。以Inherit方式使用窗体即采用了可视化继承——VFI。
3 应用实例
下面以一个实例对VFI的应用进行说明。在一MIS中,需要对多个数据库中的表格进行统计,为了获得较好的显示效果,采用了dxDBGrid控件作为显示数据结果的主要控件,并使其在统计界面中记住每次退出时的字段的位置,字段列标题的宽度等信息,因此,对每一个统计界面都提供一个窗体来实现。
为实现此要求,通常的做法是对每一个统计窗体进行如下设置:(为方便说明,下面各个组件的名称均采用了默认的名称)
1.新建窗体(为每一个统计界面提供一个窗体类);
2.放置需要的组件(放置dxDBGrid、wwDBNavigator、OpenDialog等组件);
3.设置组件属性(调整各个字段的可见性、显示宽度等);这些工作又可以细分为两类:
3.1:对所有窗体中的组件的一样的设置,如DataSource1的DataSet属性,dxDBGrid1与wwDBNavigator1、wwFilterDialog1的DataSource属性等;
3.2:各个窗体中设置不同的工作,典型的操作是设置DataSet1的数据来源,dxDBGrid1中Column的属性。
4.设置窗体及其他组件的事件属性(如在窗体打开事件中打开数据集,在窗体关闭事件中关闭数据集,在导出事件中完成dxDBGrid数据的导出)。
窗体中主要的组件如下图所示:
[发表时发现,没有该图也可以,所以省略了]
在这一过程中,有些工作是要求不同的,比如工作1、工作3;但有些工作是重复性的,工作2、工作4,在这种情况下,多个统计窗体之间,会出现很多代码的剪切、拷贝工作,既容易出现错误,在以后需要修改程序的时候,又不容易进行完全的、彻底的修改。比如,实现导出dxDBGrid1中数据的代码,就会可能出现在多个窗体中。虽然将导出数据的功能封装成函数可以在一定程度上,在各个统计窗体中进行调用的方法,可以减少这类重复性代码。但是对于组件属性的设置,及大部分事件的判断,如PopupMenu弹出事件中对是否进行“导出选定数据”可用性的判断,则必须要在每个窗体中出现。(虽然,可以在程序中设置一个通用的OnPopup事件处理,但是需要保证“导出选定数据”的菜单项具有相同的名字,或者在程序中进行判断,仍然少不了重复的工作,并且也容易出错,或者忘记设置菜单项的属性)。
而如果采用VFI,这些重复性的工作都可以解决。可以为这些统计设置一个父窗体(类名称为TFormBaseTongji),窗体如下所示:
[发表时发现,没有该图也可以,所以省略了]
所有的重复性的工作,如工作2、工作3.1,工作4都在父窗体中完成。如OnFormShow中设置代码:AdoDataSet1.Open;。
之后,各个具体的子窗体从该窗体继承而来,在子窗体中进行的设置只需要工作3.2。这样所进行的操作,将极大地减少工作量。不仅如此,使用VFI,还可以保持各个窗体之间的一致性,使之具有相似的外观,从而保证软件界面的一致性。由于重复工作的消除,也给软件维护带来了很大的好处,比如,如果要再增加一个公用功能,或者调整界面的细节,都可以在父窗体类中实现,子窗体中不再做任何工作;同时,VFI还允许子窗体,增加自己的功能,改变父窗体中的行为(即实现多态)。可以说,VFI为可视化开发提供了一个强有力的支持。
4 结束语
在重用性显得日益重要的今天,VFI为进行可视化的面向对象的开发提供了可能,有效地使用VFI,可以极大地改进程序重用性,改善程序的一致性,降低维护的成本。