Lazarus中文社区

 找回密码
 立即注册(注册审核可向QQ群索取)

QQ登录

只需一步,快速开始

Lazarus IDE and 组件 下载地址版权申明
查看: 2189|回复: 6

小议事件机制

[复制链接]

该用户从未签到

发表于 2013-5-5 14:02:51 | 显示全部楼层 |阅读模式
本来LCL库的事件机制是很好的,但是过分依赖事件机制,就会使得代码的BUG会比较多。

我们知道DOS环境的程序编写,都是基于过程的,而到了Windows系列后,都是基于事件机制。

操作系统发送给我们的程序的事件,就触发某个回调函数。

形象点,我们的GUI程序都是基于操作系统的消息的回调函数。这样的编程风格比起DOS环境编程本来就已经

复杂了很多了,我们在编写的时候,无法预知用户下一步操作是什么,会不会导致问题。

VCL, LCL这样的库将这种事件机制进行了进一步的扩展,使得基于事件(Event)的编程更加复杂化了,

比如TDataset 的 afterScrool 实际上,操作系统是没有发送类似的事件给我们的程序的,是框架提供了

这种回调接口,这种事件是一种用户自定义事件(Custome Event) , 这种扩展的好处是充分利用了框架

提供的强大模版类,如果要编写好GUI程序,我们就必须熟悉自定义事件是如何发生的,他和其他事件发生

的顺序是怎样的,否则程序会发生很多错误。

坏处就是我们的代码被分散了,比如在 beforePost里面写验证代码,实际上

我们可以在程序的保存逻辑里面进行验证,可以让程序逻辑更加清晰,易读。

所以,我们可以根据情况适当使用这种机制,而不是大量依赖这样的机制进行编程。


回复

使用道具 举报

该用户从未签到

发表于 2013-5-5 18:23:28 | 显示全部楼层
有道理!
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2013-5-6 10:41:51 | 显示全部楼层
一言道破,还真从来没从这方面考虑过
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2013-5-7 13:55:05 | 显示全部楼层
有道理。
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2014-2-6 10:13:17 | 显示全部楼层
很多事件还是很有必要的。自己最好规划就好
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2014-4-24 11:36:47 | 显示全部楼层
本帖最后由 Raymond 于 2014-4-24 13:41 编辑

多么优美、优雅、优良的一套机制,被你们说成这样?!你们研究过没有?就在这里乱扯!
1、现在的桌面操作系统,都是基于消息驱动机制的。
2、就是因为操作系统的消息机制的复杂性,VCL/LCL封装得非常好,使得开发者很方便就能进行开发。
3、TDataSet根本就没有涉及到消息的处理。你们看过源码没有?
4、每个开发工具,要用好,当然需要去深入了解这个开发工具以及相关的东西。
5、Bug多那是开发工具设计的问题,每个工具都需要非常长的时间来进行优化,哪个工具没有Bug的?
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2014-8-4 14:35:35 | 显示全部楼层
唉,面向对象的三要素:属性,方法,事件。每次我面试程序员,一般都只能说出前面两个。就算能说出事件这个单词来的,也说不清楚事件是什么意思。

你们上学的时候,老师没教过你们,分析问题,从信号的流程来分析?

一个对象,就是一个独立的功能模块。一个功能模块,就是一个处理特定信号的【物件】。好比一个硬件电路里面的一个IC,或者一片PCB板子。这样一个东西,必须要有信号的输入和输出。你想象一下,如果我们做一片电路板,做实验,有3个按钮,接3个灯。按第一个按钮,第一个灯就亮;按第二个按钮,第二个灯就闪,按第三个按钮,第三个灯就亮。三个按钮一起按,三个灯就都不亮。设计这样一个逻辑,用硬件把它做出来,不会有什么大问题吧?那么,这块板子的输入和输出是什么?

输入就是那三个按钮所接的引线;输出就是那接三个灯的引线。

如果把这个逻辑,做成一个程序,如何?

按钮是现场的(TButton),灯是现成的(TLabel 来模拟。现实【闪烁】两个字就代表闪好了。其它同理。),只要把上述逻辑做成一个【类】,也就是一个程序代码模块,比如叫 TMyPCB;然后用一个程序(Application),在一个 TFomr 里面,放上三个 TButton,三个 TLabel,一个 TMyPCB,就可以做出这样一个玩意来。

好了,TButton 的 OnClikc 调用什么代码?按下按钮,要输入数据给电路板(MyPCB),因此这个 TMyPCB 要有3个【方法】让 Button 来调用。

Button 调用它的方法后,它必须要输出信号,让 TLabel 的 Caption 发生变化。它如何输出信号?这就是【事件】。事件,是一个【类】或者说一个【物件】输出信号的东西!

再次重复:方法是一个代码模块的输入部分,事件是一个代码模块的输出部分。

从具体的 Object Pascal 代码的角度来看,方法,就是一个让别人来调用的函数。这个函数里面实现一些信号处理代码。函数的参数一般就是输入的信号(数据)。而事件,就是你的这个模块处理完信号后,要输出给别人,也就是要调用别人的方法。别人的方法你怎么知道?你不知道。所以,事件是一个方法指针。你调用的是一个方法(函数)的指针。谁想要这个输出的信号,谁就把自己的输入信号的方法的指针告诉这个模块。其实,这也就是类似于 WINDOWS 里面的回调函数。

当然,普通的函数,和面向对象的【对象方法】还是有点不一样。普通函数类似这样:
procedure DoSomething(const S: string);  它的指针应该就是一个标准的 Pointer 类型。

而方法的指针,类似这样:

procedure (const S: string) of Object,它的指针,其实要带上实现这个类似的方法的类的指针。
回复 支持 反对

使用道具 举报

*滑块验证:

本版积分规则

QQ|手机版|小黑屋|Lazarus中国|Lazarus中文社区 ( 鄂ICP备16006501号-1 )

GMT+8, 2025-5-2 20:54 , Processed in 0.030336 second(s), 10 queries , Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表