我的Delphi开发经验谈
--------
开发环境
--------
Delphi 7是一个很经典的版本,在Win2000/XP下推荐安装Delphi 7来开发软件,在Vista下推荐使用Delphi 2007开发软件。安装好Delphi 7后,应立即安装Delphi 7 Update Pack 1,Delphi 2007则建议尽量安装最新的版本。工欲善其事,必先利其器,为了提升开发效率,为了能更加得心应手的处理接下来的开发工作,我们有必要安装一些有用的开发辅助工具(Delphi将此类插件以Expert命名)。首先推荐的是DelForExp这个源代码格式化工具,集成在IDE里,使用相当方便。即使我所写代码的风格非常好,但是还是免不了阅读某些人写的乱七八糟的代码,这时DelForExp就能派上用场了,1秒钟就能让代码能看上去顺眼多了。GExperts曾经是一个非常出名的工具,可现在都不怎么更新了,里面有几个功能还是值得一用,比如Grep Search, Replace Components, Code Proofreader等。强烈推荐安装CnPack IDE 专家包,相信我,它会让你的Delphi更好用。Delphi 7是不支持重构的,因此我还建议安装Castalia,这个工具中某些功能还是很不错的。CodeRush一直都是Delphi下最强大的工具,可是由于安装后比较容易与其他工具冲突,让人不得不忍痛割爱。Delphi 7下建议安装Delphi SpeedUp这个IDE加速工具,其原理是在Delphi启动前,替换RTL的函数为来自FastCode工程的执行效率更高的函数。ModelMaker Code Explorer为Delphi增加了一些方便重构代码的功能,值得安装使用。
第一次启动Delphi 7,关闭设置中的Delphi Direct以禁止Delphi访问Borland服务器,勾选Show Compiler Progress选项以便编译程序时可以看见编译进度,然后分别设置所安装的专家的选项,再对Delphi的窗体布局按自己的喜好调整,调整好了然后将其保存为默认布局。关闭工程,设置好默认的工程选项。接下来就可以安装控件包了。如果是在项目小组中配置开发环境,因为可能所需的控件比较多,安装比较麻烦,建议由一个有经验的开发人员将那些散装控件预编译后做成安装程序供小组其他成员安装。
--------
软件设计
--------
在整理自己的思路的时候可以采用PersonalBrain来画思维导图,这是一个拓展脑力,激发思维的一个活动,并且将自己的想法全部记录下来,并在整理的过程当中可以发现内在联系与更多的问题,在接下来的设计中加以考虑。做设计需要画图,除了Visio外,我推荐EDraw Soft Diagrammer。Enterprise Architect用来做UML设计是很好的选择。ModelMaker为Delphi增加UML支持,可以保持设计与代码双向同步,非常不错的工具。
作为一个Delphi产品的设计人员,应该具有广阔的视野,熟悉.NET、Java下优秀的框架设计,熟悉Delphi类库的源代码,其中总有我们可以借鉴与学习的地方,根据公司的实际情况以及具体需求有选择的在产品开发中进行实践,这样才能做出高质量的产品。
--------
软件开发
--------
数据结构是软件开发中的基础,在开发项目前,你一定应该准备好如TStack, THashtable, TQueue, TCollection, TMap, TBag, TSet, TAssociation之类的容器类,然后在以后的开发中根据需要选用合适的数据结构,避免不要直接使用指针与TList。如有需要,可以先将TStream,TRegistry等常用类继承实现,也就是做一个包装,这样就为以后的开发中就留下了一个可以随时加入扩展的接口。
网上也能找到DGL(The Delphi Generic Library)来为Delphi增加泛型支持,实际上也可以称之为一个模板库,但是这个库我也只使用过一次,网上也未见其他人使用,因此到底是否可靠还有待于实践验证。说到模板库,我还想起一个DEEX,这是一个预处理器,可以让你使用类似STL相似的语法,其中也内置了DTL(Delphi Template Library)库。
关于AOP,Delphi这方面完全不能与Java或.NET相比,所能用的技术也就只能是动态代理或Hook来实现,虽然也出现了MeAOP之类的框架,我还是建议从设计上去解决这类AOP的需求,或者也可以考虑采用在DailyBuild的时候做编译前预处理(比如设计成{LogAction}类似于.NET的属性特性来修饰特定的方法,当然预处理器必须自己开发)。
与开发有关的文件都应该被管理起来,而不仅仅是只管理代码,一开始就要做好目录规划,特别要注意将代码与运行时所需的资源分隔开,一般来说,可以分为Doc,Src,Res,Misc四大类,Doc存放全部相关的文档,里面建立具体的分类目录;Src存放编译所需的文件,比如源代码和帮助的源文件;Res存放制作安装包与发布软件所需的各种资源文件,比如图片、网页等。这样做将为接下来的DailyBuild做好准备。
Delphi没有Package与Namespace的概念,因此只能利用目录上的物理划分代替逻辑划分,将同一性质的单元放置到同一目录,根据需要再划分更多子目录来存放单元。
程序的界面上的控件最好都重新规范命名,切忌在代码中出现类似Label1.txt := 'abc';之类的代码。开发者应该熟悉Delphi所提供的系统函数,切忌自己去实现Delphi已经提供了的函数,一则这样做的效率不高,二则你自己所写的代码没有经过完全的测试,很有可能存在未妥善处理的情况。我们不提倡重复发明轮子,特别是在正式的开发中这样做。开发中把握面向对象设计的原则:单一职责、开放封闭、里氏替换、依赖倒置、接口隔离、高内聚低耦合。代码就是最好的注释,变量命名尽可能的表达其本身的意义,最好的注释就是不需要注释也能很容易的看懂代码,只在需要的地方加上注释。开发人员应该将自己所写的代码视之为供别人使用的产品,不要随意的将方法声明为公开方法,只提供给别人需要的方法,每个公用方法上都应该用注释标明其功能。程序编译过程中出现的任何警告或提示都应该认真对待,争取消除每一个警告或提示,这样做是避免一些代码中可能存在的隐患。
有经验的程序员完成特定的功能会充分考虑可变的情况,将这些地方提取出来,定义为方法参数或者从配置文件中读取,这样即使需求发生变化,也能轻松应对。要写出易维护的程序应该在软件配置化和程序动态化上下功夫。特别提一提程序动态化,现在开发网络游戏的很多,而且一般都会用到脚本引擎Lua来实现部分逻辑,这样在开发后期的调整相对变得轻松一点,以后在服务器上做修改也不会要求重新启动程序。当然在一般的项目或产品中一样可以考虑使用脚本引擎,当然不一定要用Lua,还可以有很多别的选择。比如:DelphiWebScript,RemObjects Pascal Script,AUTOMA atPASCAL SCRIPTER,FastScript,Innerfuse Pascal Script。如果还有更高的要求,还可以考虑利用COCO/R (ParserBuilder)来实现自己的语法解析器。
开发中通常会遇到自己不能解决的问题,要知道你遇到的问题别人可能早就遇到过并解决,因此请教他人或者请教Google通常是最好的选择。上论坛提问是没有效率的方法。本地的知识库也能派上用场,比如www.delphi3000.com的离线库CodeFinder,大富翁离线资料库,
--------
控件开发
--------
控件分为不可视控件与可视控件,不可视控件其实与一般的类没什么太大的区别,只需要公布需要公布的属性为Published,如有需要也可以设计并注册自己的属性编辑器。
开发控件也有专业的开发工具Eagle CDK和Eagle reAct,您不仅可以很方便的创建类,还可以在运行期测试控件,可以很方便的修改属性,即时看到效果,大大提高了开发效率。
--------
软件破解
--------
愈来愈多的开发者开始采用RSA来作为注册的加密算法,效果还算不错,虽然仍不能防止被爆破,但是至少不会出现(内存)注册机。对软件加壳也不是什么防弹衣,对于有经验的破解者几分钟就可以用OllyDbg从内存Dump(先用Process Explorer杀掉屏蔽调试工具的线程),接着就是用Import REConstructor修复IAT,再用Lord PE对EXE进行优化。
DeDe可以让破解者看到程序内的资源,事件,既可以静态分析,也可以在OllyDbg中对分析出的地址进行动态调试。
破解Delphi控件当然也可以用DeDe,但是我们有更好的选择,那就是DCUcu与Dcu2Pas,可以将Dcu直接反编译成汇编代码,通过静态分析其中的字符串以及调用的API,破解真的是很容易。
只有做到知己知彼,才能做到有的放矢,反破解就是做到以最小的保护代价来使得破解者付出极大的破解行动。
--------
版本控制
--------
版本控制最流行的就是VSS, CVS, SVN,我比较喜欢SVN,但是由于在Delphi下始终没有很方便的连接SVN的插件,因此,仍然是Delphi+VSS是最方便的版本控制的选择。VssConneXion是专门用于为Delphi增加VSS支持的插件,确实为开发人员带来了无比的便利。Delphi+TortoiseCVS与Delphi+TortoiseSVN同样也是不错的选择。VSS最大的缺点就是只能在内网中使用,除了可以透过VPN来允许远程访问外,我们还可以用Dynamsoft SourceAnyWhere或SourceOffSite实现VSS通过Internet访问。当然VSS 2005也支持Internet访问。如果你是个人开发者,觉得使用VSS也太麻烦,不妨试试FileHamster。
--------
软件测试
--------
在提交给测试人员前,要求开发人员首先做自测,不要出现给测试人员的是一个都不能运行的版本,这样是对测试人员的不尊重。
Java有JUnit,.Net有NUnit,同样Delphi也有DUnit,这主要是用来做单元测试用的,特别是在不停的代码重构中,能够及时发现修改出的问题,是每日构建中的重要组成部分。开发人员在完成功能前就写好测试用例代码,也称之为测试驱动开发,让自己作为自己代码的第一个用户,以确保自己提交的代码是易用的、正确的;让测试人员更专注于发现那些隐藏的逻辑性错误。
TestComplete是AutomatedQA出品的专业自动化测试工具,与Rational Robot和Mercury WinRunner相比,特别适合用于Delphi开发的程序的测试。自动化测试可以减轻测试人员的工作量,提高他们的测试效率。当然,采用自动化测试对于测试人员的要求就更高了,因为需要测试人员维护测试脚本。
--------
缺陷管理
--------
测试人员的报告需要反馈给开发者,同时又要知道开发者的修改意见,上级主管需要知道当前的测试进度与修改情况,这一切都是需要缺陷管理系统所管理的。通常缺陷管理都是做成B/S系统,当然也有提供客户端的。JIRA, Mantis, Bugzilla, Axosoft OnTime, Axosoft PowerTrack, Bug Tracker, BugFree, Dev Hound, SourceGear Dragnet, TestTrack Pro, URTracker,同样有很多选择。
--------
内存泄漏
--------
Java与.NET自身有垃圾回收机制,而且没有指针,除了外部资源(数据连接,文件等)需要使用完关闭,让开发人员是不需要主动管理内存释放的,Delphi却是需要自己管理对象的创建与释放(Create and Free, New and Dispose, GetMem and FreeMem),在这一点上有些初学者往往不太注意,应坚持谁创建谁负责释放的原则。虽然Delphi下没有垃圾回收机制,但是有工具可以帮助我们检查内存泄漏。
MemProof就是一款专门用来检查内存等资源分配情况的软件。作者Atanas Stoyanov后来加入了AutomatedQA公司。
AQtime是AutomatedQA出品的专业的测试软件,包括性能分析,内存与资源分配情况,最有用的当然是性能分析与内存泄漏检测。
Fast Memory Manager,一款优秀的内存管理器,Delphi 2006以后就采用FMM替换了BorlandMM,Delphi 7下也可以加挂FMM来提升程序运行性能。同时FMM也是一个绝佳的内存泄漏测试工具。
推荐引入FMM到工程,在开发过程中尽早的发现并解决内存泄漏问题,是比较理想的解决办法。
--------
错误定位
--------
测试人员在错误追踪系统上提出了测试出来的错误,开发人员就要进行针对解决,首先就会遇到如何定位一些复杂的错误。
首先就是打断点在Delphi里跟踪调试运行,如果是在线程里或是不能跟踪调试的情况下,可以使用OutputDebugString进行跟踪输出,然后在View->Debug Windows->Event Log里查看。CodeSite是一款让开发者可以很方便的调试工具,特别是支持远程输出。此外还有小巧并且开源的Overseer也是不错的调试工具。JEDI Code Library里的Debug单元功能同样强大。
AV错误是Delphi中比较常见的未知错误。通常可以挂接Application.OnException,来自己处理所有的异常错误。在这方面,有专业的软件可以帮助我们处理异常,EurekaLog就是一款专业的异常处理软件,可以告诉我们非常详细的错误信息,使得定位错误变得更轻松。madCollection里的madExcept也是一款非常强的异常处理软件,
--------
制作安装
--------
Inno Setup与NSIS都是免费的,功能强大的专业安装制作软件,Inno Setup是Delphi开发的,因此特别适合Delphi开发的产品的安装程序制作。NSIS比较适合C开发的产品的安装程序制作。推荐Inno Setup + ISSI (Inno Setup Script Includes) + ISTool来制作安装程序。
--------
每日构建
--------
如果一个公司还是采用手工方式编译发布软件,那一定会出问题,比如将某个中文文件打包到英文版里发布出去,比如发布的软件的版本并非最终的版本。
为了确保软件发布的稳定性,不管大小公司都应该制定一套软件发布流程,并用工具来固化这个流程。
流程首先是从版本控制软件获取最新或特定版本的代码以及资源,对代码以及资源做必要的预处理(比如修改版本号,自动代码审查),编译代码,编译资源(例如帮助),编译中出现错误自动反馈(比如发送邮件),编译成功后自动进行单元测试(测试失败也会自动反馈;编译成功但是出现的警告与提示也应自动反馈),测试通过后制作安装程序,发布软件(比如上传到某个FTP,复制到某个目录)。这些流程很繁琐,如果由人来执行是不可靠的,所以要由软件来实现这个流程。
代码审查:检查代码中是否存在不符合事先约定的代码规范的动作。比如.NET下的FxCop就是用来做代码审查。在Delphi中需要自己实现审查器,加上利用正则表达式定义的代码审查规则(比如控件命名是否规范,窗体上是否使用的英文字体,公用方法上是否标有注释等)。代码审查用人工实现是没有效率的,同时也是不可靠的,利用DailyBuild来实现自动代码审查能够保证代码质量,甚至于提前发现代码中的隐患。
可以用脚本实现每日构建:比如Perl, PowerShell, 批处理等,当然只适合一些简单场合,而且对于维护脚本的人员的要求也相对较高。
Java有Ant,.NET有Nant,同样Delphi有Want(为什么叫Want而非Dant,原来Want是取Windows Ant之意,虽然Kylix可以在Linux运行,Free Pascal可以在更多的平台下运行,但是想到Want是一个命令行工具,want clean, want compile, want build,看起来很不错,于是作者还是决定用Want), Want是用XML作为配置文件,维护起来稍微有点麻烦,不过维护好XML以后执行构建的时候有WantUI界面可以使用,还算挺方便的。
FinalBuilder,一个完全的图形化构建工具,支持脚本,很好用,支持的工具也很多,唯一的缺点就是这是一个收费软件。
Visual Build Professional,同样是一个可视化的构建工具,也支持脚本,支持宏,还支持虚拟机,同样也是一个收费软件。
--------
网络资源
--------
http://www.torry.net上有很多的Delphi资源,里面有不少优秀的免费控件与代码。
随着时间的流逝,我们手上应该积累了很多的开发资源,比如电子书、文章、源码、开发工具等等,应该将其准确命名并分类存放于不同的目录中,如果体积太大,可以刻录成光盘并用WhereIsIt编目后妥善保管。像那些比较零散的文章、代码等,可以考虑使用一个文档管理软件管理起来,比如MyBase、EverNote等。管理的知识可以与他人分享交流,共同学习提高。
--------
其他补充
--------
JEDI Project:JEDI Code Library 和 JEDI VCL 是Delphi下最大的两个开放源代码的工程,值得好好研究。
KOL+MCK:VCL的确很方便,可是代价便是程序体积的增加,KOL(Key Objects Library)+MCK(Mirror Classes Kit)便是VCL的一个替代品。
DWPL(The Delphi WDosX Project Library):让Delphi编译的Console程序能够运行在DOS下。换句话说就是开发32位的DOS程序,用Turbo/Borland Pascal开发的是16位程序。
Free Pascal/Lazarus:Free Pascal是一个32位的编译器,并且支持多平台,也可以算是Delphi的一个近亲,另外一个是TMT Pascal。Lazarus则是一个Free Pascal的集成开发环境,界面类似Delphi。