在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