在te2和iws的开发过程中,我终于体会到了采用组件开发的方式给我带来的非凡的快乐和巨大的痛苦,一方面,我可以简单的拖拉几个组件放在form或者datamodule上,设置一下属性,接着我就可以按f9来run了。另一方面,我常常陷于莫名其妙的av错误中,一不小心就会把我的delphi搞崩溃。但是,只要我们搞清楚了创建组件的一些基本方法,那么就可以小心的避开组件开发过程中的种种陷阱。在阅读这篇文章之前,我建议大家可以先读:
- delphi爱好者上的:form class to component,这篇文档告诉我们创建组件的基本方法
- creating components dynamically,这篇文档告诉我们使用组件的正确方法
- dynamic component creation gotcha (don't do this),这篇文档告诉我们使用组件的负作用
- reuse through inheritance and composition,这篇文档告诉我们如何设计组件
- 10 guidelines to help you design for reuse,这篇文档也告诉我们设计组件一些可以操作的办法
我写这篇文章的目的是希望我们能从过去的rad开发方式中转变成基于组件的开发方式,但是这篇文档并不告诉大家如何写组件,及写组件的一些方法,因为那几乎可以写成一本书了。
为什么用组件?
现在开发领域中比较热门的话题是oo及基于oo的更加偏重于问题域的patterns,在我刚刚开始使用delphi的时,我常常自问:我采用了oop吗?让我们来看看使用delphi 开发的标准方式:往form或datamodule上放置几个组件,写几个事件,按f9 run 。是的,rad令我愉快的编程,但是它不会导致我认真设计:
- 开始阶段代码并不会复杂,好多时候我们会把一些通用的代码拷贝到程序的各个地方,而且这些代码看起来好象不能复用,最简单的例子就是:在某个action的execute事件中我创建一个query,执行一个sql,在另一个action的execute事件中我又会创建一个query去执行另一个sql,这里有没有什么办法来抽象创建query的过程?
- object inspector非常好用,我可以非常容易的写事件处理逻辑,但是这会把逻辑和form或datamodule紧紧绑定。尽管把业务逻辑写在datamodule中是delphi推荐的方式,但它的复用程度并不怎么好,想想在一个datamodule中放置几十个数据集的情况,你还能说这个datamodule可以复用吗?
所以,我推荐使用基于组件的编程,why,让我们看看form class to component中写到使用组件的三个优点:
- delphi有一套组件的动态创建和销毁的机制,反之,tobject的派生类必须显式的在代码中创建、使用、销毁。
- 你可以在设计时设置属性,不要小看这个优点,我们可以开发出属性编辑器,可以让用户只能选择合法的属性值。
- 对于可视组件,你可以在设计时设置组件的位置和大小。
这只是显而易见的优点,它只是表象,隐藏在这些优点下面的精髓是:oop。delphi提供了一个组件框架,所以当你开始试图通过写组件来简化编程的时候,你就会不知不觉的采用oo的编程方法。最为重要的是vcl框架采用了许多让程序易于重用的设计模式:
- composite 模式:当你在form上放置各种组件,组成一个新的tform的派生类,你用到了composite 模式
- builder 模式:当你创建你定义的form时,你会使用builder模式,通常builder模式创建的对象是由composite模式组成的。
- template method 模式:这个模式太普遍了,任何一个从tcomponent的派生的类,都会使用该模式!
- mediator 模式 :当你写事件时,你用的正是mediator 模式,注意了mediator 模式中的缺点就是:它会使中介者为一个庞然大物!
- singleton 模式:尽管没有任何机制阻止我们创建多个tapplicaion对象,但是我们知道任何一个gui程序只能有一个tapplcaiton对象,那就是全局变量applicaion。
当你开发组件时,你已经开始使用oop,并且将会使用上面的五种模式。至少从理论上已经保证你的代码是可以重用的,你的程序是易于更改从而适应更多的需求。
mail to:me