孟岩ID:myan
[修改头像]
1557551次访问,排名6好友1人,关注者32
总是在思考存在的问题
myan的文章
原创 146 篇
翻译 0 篇
转载 3 篇
评论 5200 篇
最近评论
YuLimin:我当时也在成都,大家都来尽一份力量吧!!!
sxbluebird:我老家后山有棵老苹果树很时尚,谁能看见?我公司桌面上有台PC很时尚,公交车上哪个mm会暗送给我秋天的菠菜?


这个话,说的太经典了。 人人都能懂, 这才是哲理。
Terry001:成都地震发生的时候,我正在午睡,我一般睡的会很死,房子把我摇晃醒了,太恐怖了,结果没穿衣服就冲下了楼,搞的甚是狼狈,从来没想到此生也有裸奔的时候。
直到现在,心情都没稳定下来,不过比512好多了,但是还是很担心余震,现在做在家里上网心都是虚的。成都今天不知道从那里报出的消息要缺水了,结果超市的饮用水一强而空。
目前感觉头脑是昏的,时不时会感觉在晃。目前待在成都似乎是一种折……
yeka:没想到成都这么严重!
lschou520:怎么会忘记印度、日本和欧洲呢?
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes
文章分类
收藏
    相册
    测试
    友情链接
    老赵的博客
    存档

    原创 评C#事件处理

    新一篇: Lua让我脸红

    前几天学了一点C#,没当真的。因为要搞《MSDN开发精选》的缘故,完全不懂也说不过去。没看什么语言方面的书。也就是把Jefferey Richter的《Applied .NET Framework》(李建忠译本)找来翻翻。看到event那一部分就烦了,原来C#的delegate和event只是表面光,下面的实现还是非常笨重。一个长长的链表,里面放着闭包指针,类型是够安全了,付出的空间和时间效率都不小。对我我这种从C语言爬过来的人,就是觉得不爽。

    事件处理机制是C++及其后继者(Java、C#)的最大软肋之一。本质上是因为C++当年的选择,把对象之间的普通消息传递用成员函数调用给解决了。成员函数调用快是够快,但是导致了消息发送者与接受者之间的紧耦合。大多数情况下这倒也并不是什么大不了的事,偏偏在事件处理上,实践中需要松耦合,于是C++的问题就暴露出来了。君不见,所有用C++写的GUI Framework都在event这件事情上大做文章。比较笨的如MFC的全局映射表,比较聪明的如Qt的Signal/Slot,一个例外是VCL,Borland实现了closure指针,把caller context跟指针绑到一起发送给callee,Java比较中规中矩,按照最OO的方式实现了事件处理机制,但是可扩充性不好。C#的delegate其实就是VCL中closure指针的新版。总之是八仙过海,各显其能。但是我觉得,都是在C++已经走歪的老路上徒然努力。只要这个思路还在,事件处理就不可能非常elegant。C#可以让整件事情在表面上看起来很漂亮,可是骨子里还是邋遢的。

    就个人而言,我还是比较欣赏C的办法:规定一个协议,我把event数据准备好放在一个地方,然后就不管了,事件的接受者自己去取数据,自己解析,自己决定如何处理。

    这样的接受者,在对象分类中,叫做主动对象——active object。这两年在embedded system programming中间,大家越来越发现主动对象的种种优势。我个人觉得主流编程领域也应该考虑一下这个问题。

    主动对象的问题可能是类型不安全,但实际上类型安全没有那么重要, 没必要死抱住不放。原来C语言里:
    int (*compare)();
    声明的指针可以指向任何返回整数的函数,不管其参数列表如何。在C++里面,这个指针只能指向一个返回整数的无参函数了,灵活性大大降低。也难怪open source人士还是偏爱C。虽然安全性和灵活性同等重要,但是真正的黑客可以用自己的技术来保障安全性,却无法接受灵活性的缺失。

    扯远了。

    总之,看得越多,越觉得C真是一种伟大的语言,大概只有Fortran和LISP跟它处于同一级别。

    附带提一句,李建忠翻译的质量极高,令我辈叹服。

     

    发表于 @ 2004年04月21日 13:56:00|评论(loading...)|编辑

    旧一篇: 希特勒生日(4月20日)

    评论

    #redforks 发表于2004-09-07 01:42:00  IP:
    TrackBack来自《语言越低级,运行效率就越高吗?》

    Ping Back来自:blog.csdn.net
    #artpro 发表于2004-04-21 16:56:00  IP: 220.248.12.*
    “就个人而言,我还是比较欣赏C的办法:规定一个协议,我把event数据准备好放在一个地方,然后就不管了,事件的接受者自己去取数据,自己解析,自己决定如何处理。”

    这种事件传输的方式应该和C语言没有任何联系吧!
    在OO中,同样可以这样做。
    发送者甚至可以把一个包含一定行为的event传递给一个接收者。
    接收者接到之后,不用自己解析,或者决定如何处理,只要调用event中的某一个接口,由event决定如何处理。
    类似于Command模式。
    这种方式是不是更优越一点?
    #myan 发表于2004-04-21 17:12:00  IP: 218.247.132.*
    不,Command模式不是一个好的解决方法——否则,为什么没有任何一个大型GUI Framework采用Command模式作为事件处理方法?关键在于,运用Command模式,caller可以把自己的context包装在object里,但是callee却只能调用cmd->execute(),无法把自己的数据传递给execute()。而事件处理不但需要caller的数据,也需要callee的数据。你也许会说,给execute()加一个参数不就行了?不行,因为那样的话,Caller就必须知道callee的类型,紧耦合又产生了 :-(

    当然,消息传递的方式与语言无关,但是用C语言来做这件事情的时候,你会很自然地采用这种松耦合的方法,就是类似Win32 API的那种方法 :-) 所以我把功劳算在C上,呵呵,是有点故意模金的意思。

    #韩磊 发表于2004-04-21 17:42:00  IP: 218.247.132.*
    C运行效率高,开发效率对于我等懒人就无法忍受了。
    #artpro 发表于2004-04-21 17:52:00  IP: 220.248.12.*
    Command类就是用来封装事件数据的啊!既可以封装caller的数据,也可以封装callee的数据啊!

    例如,下面的Command:

    class ConcreateCommand
    {
    private:
    int caller_data;
    int callee_data;
    public:
    void SetCallerData(int i);
    void SetCalleeData(int i);

    void Execute();
    };

    callee调用时:

    cmd->SetCalleeData(xxx);
    cmd->Execute();


    Command用来封装双方的数据,caller和callee之间松散耦合。
    #myan 发表于2004-04-21 22:26:00  IP: 218.246.7.*
    呵呵,例子好看,却只能适用于最简单的情况,于实用无益。表面上看去是松耦合,实际上耦合得更紧密了。协约在接口之外,你设计时必须想清楚execute()中要用到哪些数据,各以何种方式映射到cmd对象中。这就已经不容易了。更何况还有很多时候,execute所需要了解的context,远不是几个数据那么简单。Callee可能要在不同状态下做出不同的判断和操作,因此需要提供不同的数据,这些如果都要事先预见到,你要花多大的智力代价?且不论你需要给Command写一大堆派生类。

    GoF说,Command is object oriented style of callback。所以我们最好只把它当成callback来用。
    #artpro 发表于2004-04-22 10:02:00  IP: 220.248.12.*
    Win32 API接受消息的函数。如:

    LRESULT WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

    就是应用程序传递给系统的一个callback函数,系统需要发送消息的时候回调这个callback。
    wParam和lParam对于不同的事件,有不同的含义。这是发送者和接收者之间的约定。这类似于不同的Command子类对Command中封装的数据有不同的解释。

    所以,在OO中,Command确实可以用来替代这个callback,作为消息传送的机制。耦合程度两者应该是相似的。
    #myan 发表于2004-04-22 10:34:00  IP: 218.247.132.*
    呵呵,反了,兄弟。Command模式中caller是callback,Win32 API中,callee是callback,不一样的。请仔细考虑一下。
    #artpro 发表于2004-04-22 11:20:00  IP: 220.248.12.*
    请看设计模式中的这段话,这里sender和receiver之间的关系和你说的caller和callee之间的关系应该是相似的吧:

    5.12 Discussion of Behavioral Patterns

    The Command pattern supports decoupling by using a Command object to define the binding between a sender and receiver:


    anInvoker(sender) anCommand aReceiver(receiver)
    |             |         |
    |----------Execute()--------->|----Action()------>|
    |             |         |


    The Command object provides a simple interface for issuing the request (that is, the Execute operation). Defining the sender-receiver connection in a separate object lets the sender work with different receivers. It keeps the sender decoupled from the receivers, making senders easy to reuse. Moreover, you can reuse the Command object to parameterize a receiver with different senders. The Command pattern nominally requires a subclass for each sender-receiver connection, although the pattern describes implementation techniques that avoid subclassing.
    #myan 发表于2004-04-22 11:50:00  IP: 218.247.132.*
    如果你坚信用Command模式可以解决问题,不妨试一试用Command模式来包装Win32 API,做一个最简单的GUI Framework,体验一下。不瞒你说,我2001年在Windows CE试过多种办法,其中也包括command模式。效果不好。我做出来了,但是跟SDK自己的方法相比,显得非常笨拙,除了可以对外宣称“使用了command模式”之外,没有获得任何好处。我觉得这就叫做滥用模式,我是引以为戒的。
    #artpro 发表于2004-04-22 13:36:00  IP: 220.248.12.*
    我非常同意你的观点:只有实践才是评价模式的唯一标准。
    但是,不能依据你、我的实践,也许,我们都还没有完全理解设计模式的精髓。
    为什么JohnVlissides能很好地使用Command模式在Unidraw Framework中作为消息传输的手段?
    #myan 发表于2004-04-22 14:08:00  IP: 218.247.132.*
    不知道你意识到没有,当你抬出Vlissides的时候,实际上已经承认了command模式在这个问题上的虚弱无力。

    我不了解John Vlissides的工作,但是他的成功不能改变我的观点。这并不是我迷信自己的实践,而是因为command模式并没有被作为主流技术而在工业级产品中广泛使用,在这一幕出现之前,我只能认为他是实验室里的成功。而且我也说过,我自己“成功”地用Command模式包装过Win32 API,只不过这种“成功”没有实际价值。如果非要进一步琢磨,非要把这个模式运用于这个用途,我相信不必等到Vlissides亲自出手,你我也可以做出来。但在强类型语言中,设计方案肯定比较复杂。而你知道,设计越复杂,适应性越差,可理解性越差。你说是一个一般人都能理解的方案更优秀呢,还是一个非要大师级人物才能搞定的方案更优秀?你练十年屠龙剑术能够达到的效果,一个书生学习步枪射击20分钟就可以达到,你觉得是宝剑先进,还是步枪先进?

    我反对技术评价的不可知论。比如你的说法:“没有完全理解设计模式中的精髓”。这种说法永远正确,因为无法反驳,无论你学到何种程度,我也可以这么评价。这不是我评判一项技术的态度。能不能尽可能简单灵活地解决问题,才是关键的。我认为设计模式很大程度上是在绕过强类型检查,获得一些运行时灵活性,这个东西被抬到了过高的位置上。事实上没有必要顶礼膜拜。如果你使用Ruby等动态语言,你会发现很多设计模式的存在纯属多此一举。如果你脱离语言和OO的束缚,更加深入底层,你又会发现存在很多更简单的解决办法。

    感谢你与我的讨论。我想我们都有自己的道理,不过请你理解我看待这类问题时的视角:simple is superior. 我曾经迷恋过精致的设计模式结构,但是现在我已经对此不感冒了。
    #artpro 发表于2004-04-23 13:14:00  IP: 220.248.12.*
    下面是我对“简单”这一概念的一些看法:

    我觉得现在的软件开发领域、软件教育领域由于看到使用设计模式经常导致“过分设计”而走向了另一个极端,略微夸张一点,我感觉很多人持有下面两个观点:

    1、不使用设计模式得到的设计一定会比使用设计模式得到的设计简单
    2、经验少的人做出的设计一定简单,或者经验少的人能看得懂的设计一定简单

    最近我们公司把“状态”模式应用在了公司的一个项目上,我可以比较一下老的设计和使用了“状态”模式的设计:

    在老的设计中,设计人员用了很多成员变量、甚至是全局变量来保存系统的状态,在代码中到处是根据状态进行判断,然后决定作何处理的if-else、switch-case,有的函数中if-else、switch-case一层套一层,对于同一个状态变量的判断分散在了系统的很多类中。

    在使用了“状态”模式的设计中,这些保存状态的成员变量和全局变量都不见了,设计人员只要画出状态迁移图,每一个状态类中的代码就很清晰了,在该状态下,收到哪种消息应该做何种处理,然后迁移到另外的哪种状态,一目了然,每一个状态类中的代码几乎可以和状态图一一对应起来。改变系统的处理方式,即添加新的状态、改变旧的状态也变得非常容易。


    在我们的项目组中,可以明显地感觉到,没有经验的、搞不懂状态图和状态模式的程序员,对于这两种设计方式都很难理解。
    而那些理解了状态图和状态模式的程序员,他们同样很难理解和维护老的设计,可是对于使用了“状态”模式的设计,他们理解起来就得心应手了。
    因此,比较这两种设计,我可以说,使用了“状态”模式的设计更为简单,是“状态”模式把复杂的事情变简单了。

    所以,我的想法是:那些经过实践验证的技术使复杂的事情变简单了。
    正像物理学中,牛顿力学、爱因斯坦的相对论使我们认识世界的能力不断增强,它们使复杂的世界逐渐变得简单。
    软件领域也应该是这样:OO的出现,使我们认识软件的能力增强,软件开发变得比面向过程时更为简单。而设计模式则试图解决OO中存在的一些交互复杂的问题,使这些交互变简单,虽然滥用模式可能造成复杂度增高,但是我觉得设计模式的根本目的是使设计变得简单。

    如果经过实践验证的技术能使复杂的事情变简单,那么只有掌握了这些技术的人才能理解这些简单的设计,因此,应该是理论知识更强、经验更丰富的设计人员更容易得到简单的设计,更容易理解简单的设计。刚从学校出来的程序员的薪水低于有经验的老程序员,程序员的薪水远高于餐馆刷盘子的,也应该能够证明这一点。

    假设我和Vlissides面对同一个需求,我作出的设计可能是拐弯抹角的,而Vlissides可能会作出一个简单的设计,我看了Vlissides的设计可能会恍然大悟:“啊!原来还可以这样做!我怎么没想到呢?”

    如果说我学习了步枪射击20分钟,那Vlissides就是练了十年的阻击步枪,我和他交手,还不胜负立判?

    这只是我的个人观点,不会被批为“唯技术论”或“迷信权威”吧?
    #hunter_gio 发表于2004-04-30 09:53:00  IP: 218.107.151.*
    ==>看过myan的好多文章,先谢谢了,说的不对的地方,还请多多指教

    前几天学了一点C#,没当真的。因为要搞《MSDN开发精选》的缘故,完全不懂也说不过去。没看什么语言方面的书。也就是把Jefferey Richter的《Applied .NET Framework》(李建忠译本)找来翻翻。看到event那一部分就烦了,原来C#的delegate和event只是表面光,下面的实现还是非常笨重。一个长长的链表,里面放着闭包指针,类型是够安全了,付出的空间和时间效率都不小。对我我这种从C语言爬过来的人,就是觉得不爽。

    ==>小弟最近也在看C#的东西,哎,没办法,谁让我们用他的.NET平台那?只能遵守他定的协议了。

    事件处理机制是C++及其后继者(Java、C#)的最大软肋之一。本质上是因为C++当年的选择,把对象之间的普通消息传递用成员函数调用给解决了。成员函数调用快是够快,但是导致了消息发送者与接受者之间的紧耦合。大多数情况下这倒也并不是什么大不了的事,偏偏在事件处理上,实践中需要松耦合,于是C++的问题就暴露出来了。君不见,所有用C++写的GUI Framework都在event这件事情上大做文章。比较笨的如MFC的全局映射表,比较聪明的如Qt的Signal/Slot,一个例外是VCL,Borland实现了closure指针,把caller context跟指针绑到一起发送给callee,Java比较中规中矩,按照最OO的方式实现了事件处理机制,但是可扩充性不好。C#的delegate其实就是VCL中closure指针的新版。总之是八仙过海,各显其能。但是我觉得,都是在C++已经走歪的老路上徒然努力。只要这个思路还在,事件处理就不可能非常elegant。C#可以让整件事情在表面上看起来很漂亮,可是骨子里还是邋遢的。

    就个人而言,我还是比较欣赏C的办法:规定一个协议,我把event数据准备好放在一个地方,然后就不管了,事件的接受者自己去取数据,自己解析,自己决定如何处理。

    ==>我只用过mfc,我觉得表现还不错,“C的办法”我觉得有利有弊。

    这样的接受者,在对象分类中,叫做主动对象——active object。这两年在embedded system programming中间,大家越来越发现主动对象的种种优势。我个人觉得主流编程领域也应该考虑一下这个问题。

    主动对象的问题可能是类型不安全,但实际上类型安全没有那么重要, 没必要死抱住不放。原来C语言里:
    int (*compare)();
    声明的指针可以指向任何返回整数的函数,不管其参数列表如何。在C++里面,这个指针只能指向一个返回整数的无参函数了,灵活性大大降低。也难怪open source人士还是偏爱C。虽然安全性和灵活性同等重要,但是真正的黑客可以用自己的技术来保障安全性,却无法接受灵活性的缺失。

    ==>函数指针的灵活性,可以用对象封装来弥补

    扯远了。

    总之,看得越多,越觉得C真是一种伟大的语言,大概只有Fortran和LISP跟它处于同一级别。

    ==>绝对同意C is GREAT!!!!!!

    附带提一句,李建忠翻译的质量极高,令我辈叹服。

    #earthharp 发表于2004-04-30 18:49:00  IP: 219.138.4.*
    C就是最基础的机器
    是机器就跳不出C

    高层的东西只不过是为了满足多数人所需要的愚昧
    #Ninputer 发表于2004-04-30 23:29:00  IP: 221.226.4.*
    和Fortran、Lisp在同一时代的语言是BASIC,C和Pascal还在后一阶段。Java和C#还是小孩子。
    #doggyzone 发表于2004-05-03 09:54:00  IP: 218.242.124.*
    支持myan的做法。Command模式我用得很多很多,但是就是解决不好callee回传的问题。甚至在很多实际应用中,caller传出的参数都很难处理。只要系统做一点点小的扩展,原来的command马上挂掉,必须重新设计接口啦,参数啦……相比之下,raw memory块真的还是比较适合这种事情。做得越多越OO,发现反而越来越像C……。
    #laoyao 发表于2004-05-06 16:50:00  IP: 218.75.204.*
    设计模式确实与强类型有相当的关系,而win32 API的设计,尤其是HANDLE,消息影射又确实是工业的实际解决方法。

    强类型的目的无非是程序正确性检查和效率的优化,带来的问题是死板。如何即满足强类型的目的,又实现动态类型可能是现代运行系统的一个着眼点。




    #laoyao 发表于2004-05-06 16:52:00  IP: 218.75.204.*
    不过要重新设计一个运行体系,难度又比遵循一个两个模式大多了
    #flyinair 发表于2004-05-19 13:21:00  IP: 24.81.209.*
    只要系统做一点点小的扩展,原来的command马上挂掉,必须重新设计接口啦
    ---------------------------------------
    再加一个间接层如何?
    我看设计模式,就是增加间接层,达到灵活性。
    根据专家意见,一般间接层以三,四层为宜。
    一家之言,欢迎指正。
    #周星星 发表于2004-06-02 08:55:00  IP: 218.2.111.*
    我也研究过C#,确实没找到一个胜于C/C++的好技术,虽然在白痴眼中那些都是C#的法宝。
    #xxx 发表于2004-06-02 20:34:00  IP: 220.184.153.*
    楼上的太偏了吗,c#做为一种新语言,吸收各家之长,的确有很多优秀的地方。你知道C++有哪些缺点吗,而C#又是如何避免的。仔细研究一下吧。
    #togalland 发表于2004-06-15 18:36:00  IP: 218.108.48.*
    主动对象的问题可能是类型不安全,但实际上类型安全没有那么重要, 没必要死抱住不放。原来C语言里:
    int (*compare)();
    声明的指针可以指向任何返回整数的函数,不管其参数列表如何。在C++里面,这个指针只能指向一个返回整数的无参函数了,灵活性大大降低。......

    =====>>这个在C++里面定义成int (*compare)(...)不就可以了吗?
    #togalland 发表于2004-06-15 19:04:00  IP: 218.108.48.*
    还有,我觉得Command模式和 Callback 机制两者事实上是一样的, 可以理解为Command模式在更抽象的层次是实现了Callback 机制. myan说的“规定一个协议,我把event数据准备好放在一个地方,然后就不管了,事件的接受者自己去取数据,自己解析,自己决定如何处理。”这一句话中,遗漏了事件的接受者怎么去取数据的说明。事实上“自己去取”应该理解成由操作系统或者其他的线程驱动触发事件。Callback机制是需要操作系统来支持的,而command模式中的command对象正好从中扮演了一个操作系统的角色,这些都是本质上相似的。而且,command对象还封装了对数据的打包解包工作,使得代码在结构上更加简单优化,显然比Callback机制更加直观。

    我不知道目前command模式到底有哪些应用,是不是真的很少(除了用于undo-redo方面),而我也只知道windows中是使用了callback机制的。但是,如果command模式确实没有在目前的工业应用中广泛使用,我觉得一个原因就是C++尚未真正的得到大规模的应用,因为就是在美国,美国国防部也才从去年刚开始采用C++作为军工软件开发语言。
    #gogalland 发表于2004-06-15 19:23:00  IP: 218.108.48.*
    另外,在WSE2.0中很好的支持了CallBack机制。我想实现原理应该是:client段注册到Server端,在server端调用在Client端的delegate,然后由delegate调用Callback函数。在这里,Server端的打包routine以及client端的delegate共同构成了Command模式中的command对象。

    事实上,事件的触发必须要先知道事件的处理函数。在事件处理上,Callback机制和command模式在原理上没有什么不一样的。
    #xxx 发表于2004-06-03 17:19:00  IP: 220.191.34.*
    在windows中,active object本来都把最单纯的硬件事件封装成了对象。楼主的意见是又要把active object再看做是事件产生源,再使用事件队列的技术,又变成过程化设计。可能还要进一步的再把这个过程处理封装,分配到对象中来处理。

    不过这种看似迂回的方法,在程序中还是常用的。有人常常设计类似于消息循环的结构,针对于自已的特别运用(不和window自身的消息循环搀和在一起)。
    #seacloud 发表于2004-06-06 12:29:00  IP: 61.170.246.*
    我也来说说Delete/Event.
    看看C#的动机很简单,毕竟C#应该算是.NET开发的第一语言了。
    在看到Delete/Event之前,我还是觉得C#还是挺干净的,看着
    也舒服,尤其我有C++/Java的经验,看C#没遇到什么障碍,照
    我当时的估计,如果实际要用C#开发,我只要熟悉一下.NET的
    类库,以及.NET和传统模块,比如和DLL,COM的交互就应该可以
    了。然而看到了Delete/Event后,我晕了,我就搞不动C#有了
    interface后为什么还要引入Delete,就因为Delete可以包含只要
    签名一样的各种函数吗?像消息机制,Java不是做的很好吗,虽
    说稍微有点笨重,但我想我们还是可以忍受的吧。至于Event,更
    是让人倒,我编译了MSDN里的关于event的例子,发现如果我
    去除了event,一切还是OK,运行没有任何问题。那么到底event
    拿来干嘛呢?我的第一想法就是可能我在模块A里申明了event,
    那么如果我在别的地方引用模块A,那么开发环境就可以自动识别
    出event来,让我直接在IDE里处理事件,然而我在VS2003里好像
    做不到这一点,当然,可能是我的方法不对,然而我自己手动
    编写代码,激发或响应模块A的事件一点问题都没有。
    既然这个想法失败了,我总得另外找找线索吧,于是稍微看了一下
    Microsoft IL,然后反编译了一下VS2003生成的代码才发现,编译
    系统遇到了event后,就会再对真正的事件delete再做一层封装,确
    保再模块外部无法直接调用delegate的同时可以允许在模块外部
    对delegate进行类似+= -=的操作。我晕啊,就为了这点小事,
    MS在编译器层面,语言层面都付出了努力。还是喜欢Java的方式
    ,Java看起来更干净一些。

    虽说要BS一下C++的惜关键字如金,一个static到处用,居然还
    有=0这种申明pure function的做法,然而,C#的关键字也太多
    了一点,^_^

    再就是要BS一下微软的文档,看MSDN我怎么都看不出event存在
    的目的,最终居然是反汇编才得到答案,不知道是我的E文水平差
    呢还是MS的文档......,其实delegate/event机制很简单,而MS的
    文档确罗里罗嗦了半天,我想这才导致了MS开发平台上有很多
    重量级的书出现了吧,呵呵...
    我曾经翻过IBM AIX的程序员手册,一个字,爽。该说的全说了,
    清清楚楚,BTW, E文的。

    纯属一家直言,大家见笑啦。回复:评C#事件处理
    #unruledboy(灵感之源) 发表于2004-06-07 09:10:00  IP: 218.19.2.*
    我发现周星星同学对微软的新技术都特别憎恶,唉。。。回复:评C#事件处理
    #周星星 发表于2004-06-09 12:32:00  IP: 218.2.111.*
    我对微软的新技术不憎恶,反而觉得它很牛;
    比如 ADO,我研究过ODBC API,当然ODBC API非常出色,但她为了简化而做了太多了封装,使自己变得臃肿繁杂,其结果与出发点正好相反,而ADO就底层得多,可控性强了,同时又清晰明了,但我从来不用ADO,也不建议其他人使用ADO,因为ADO基于COM技术,而我上述所说的所有优点都与COM无关。所以我反对的是 M$给我们一顿美食(比如ADO)却又在里面加上鸠毒(比如COM),类似的还有DirectX。
    回到你关心的.net上来,请问M$这么多的好技术(比如webservice)中哪一种技术是非.net和C#就不可实现的?M$将webservice只做在.net中我当然要反对,在商业上强制搭配销售是非法行为。
    #yaotiebing 发表于2004-06-23 14:29:00  IP: 61.172.200.*
    C is GREAT!!!!!! =====〉汇编 is great
    #www 发表于2004-06-23 17:58:00  IP: 61.51.131.*
    主动对象的问题可能是类型不安全,但实际上类型安全没有那么重要, 没必要死抱住不放。原来C语言里:
    int (*compare)();
    声明的指针可以指向任何返回整数的函数,不管其参数列表如何。在C++里面,这个指针只能指向一个返回整数的无参函数了,灵活性大大降低。也难怪open source人士还是偏爱C。虽然安全性和灵活性同等重要,但是真正的黑客可以用自己的技术来保障安全性,却无法接受灵活性的缺失。

    ====================================

    一门语言是主要是给大众用的还是给黑客级高手用的? 黑客当然不会喜欢C#,因为C#不可能让他做太多坏事
    #Semigod 发表于2004-06-24 08:30:00  IP: 219.136.164.*
    才只是看了看就乱评,浮燥!
    #seacloud 发表于2004-06-24 09:19:00  IP: 218.80.44.*
    呵呵,高手才可以很快抓住问题的本质啊!
    #Xuefeng 发表于2004-06-24 20:11:00  IP: 61.55.134.*
    delegate真是麻烦,我到现在还没有真正用过一次。我在Java中用接口就好好的,回调很容易实现,不需要额外的event,让人不容易把握程序的本质。

    另外,C#也夸张了点,用unsafe本身就违背了IL语言的初衷,最近看到好像还能用_asm,晕!回到C++级别了!

    还是Java的OO最简单,不过现在也弄个generic越来越像C++了。

    要说最NB的语言,还是C,不过开发效率就差远了。所谓面向对象,很多人C++写出来的就和C没什么区别。真正实现面向对象,就必须封装成组件,不然写着写着就又变成面向过程了。
    #wwwsq 发表于2004-06-25 10:09:00  IP: 218.109.44.*
    设计模式很好的,但是不能滥用。设计模式基本上属于经验总结;经验丰富的人不用看设计模式也在用那些模式,没经验的人看了设计模式也不知道该何时何地如何用模式。
    #透明 发表于2004-06-26 16:16:00  IP: 218.108.196.*
    >>没有任何一个大型GUI Framework采用Command模式作为事件处理方法

    WebWork就是用Command模式的,web UI也可以算是GUI的一种吧?

    >>类型是够安全了,付出的空间和时间效率都不小

    当用户的每次操作涉及一个网络连接和一个数据库连接时,当监听器通过网络接收异步消息(例如JMS)时,这点效率损失又算什么?当你的系统涉及数十种消息类型时,当你的系统同时发送数千条消息时,恐怕类型安全和事务保证才是最重要的。请注意,这不过是一个最平凡的web应用的场景而已。
    #ChenA 发表于2004-07-09 15:39:00  IP: 220.248.6.*
    就个人而言,我还是比较欣赏C的办法:规定一个协议,我把event数据准备好放在一个地方,然后就不管了,事件的接受者自己去取数据,自己解析,自己决定如何处理。
    看到event那一部分就烦了,原来C#的delegate和event只是表面光,下面的实现还是非常笨重。一个长长的链表。

    这有区别吗?delegate不就是把caller的数据放在event(我自己的托管模式是caller的指针),也是自己解析,自己处理,而且事件的接收者自己去取的过程在某些情况下可以做到自动化,比如UI,可以写一个基类包含一些基本的event,所有的界面类就都不用写了。我觉得delegate只是减少藕合,caller和callee必然有关联。至于链表,用c就不用链表了?没学过c,还请讲解讲解。

    int (*compare)();
    至于这个用模板偏特化可以托管给任意类的任意函数(static和非static)和任意全局函数。

    主动对象的问题可能是类型不安全,但实际上类型安全没有那么重要, 没必要死抱住不放。
    c可能是灵活,但是c++即可以安全也可以灵活。两个不是一个级别的东西。佛教讲究虚无,但一个傻子他可能看什么东西也是虚无。举个不恰当的例子,c和c++就好像这种关系。
    #redforks 发表于2004-09-07 00:37:00  IP: 221.218.32.*
    delegate 的运行效率是很高的,在.net 2中速度比接口调用还要快。运行时,运行环境直接创建目标函数的调用Stack,然后就Call目标函数,其实和直接调用函数过程很类似。
    #redforks 发表于2004-09-07 01:43:00  IP: 221.218.32.*
    这里太短了,写不下,请到这里察看: http://blog.csdn.net/redforks/archive/2004/09/07/96384.aspx
    #zhuam 发表于2004-09-22 09:51:00  IP: 218.106.89.*
    赞同孟岩的部分观点,

    技术是不能过份的崇拜,不然你跳不出这到圈子!!

    永远无法达到前人的高度!





    #CSDN管理员 发表于2004-10-18 14:42:00  IP: 211.138.31.*
    http://blog.csdn.net/redforks/archive/2004/09/07/96384.aspx
    #deavilness 发表于2005-03-11 17:27:00  IP: 202.105.21.*
    ========================================
    >不,Command模式不是一个好的解决方法——否则,为什么没有
    >任何一个大型GUI Framework采用Command模式作为事件处理方
    >法?关键在于,运用Command模式,caller可以把自己的context
    >包装在object里,但是callee却只能调用cmd->execute(),无法把
    >自己的数据传递给execute()。而事件处理不但需要caller的数据,
    >也需要callee的数据。你也许会说,给execute()加一个参数不就行
    >了?不行,因为那样的话,Caller就必须知道callee的类型,紧耦
    >合又产生了 :-(

    不明白楼主为什么有这种奇怪的想法。

    即使是C 语言的 Callback 函数,也不能改变被调用者的 callback function 形式。在参数方面,Windows 的 API 采用了一个比较笨拙的方法,就是传个地址过去,然后强制转换成所需要的类型。而这种方式,用了一种 struct 包含的结构实现了对“继承”的一种模拟。这种 struct 实现的模拟继承,把代码和编译器的物理结构紧紧的联系在一起了。

    既然 C 语言的 callback 不能改变被调用者的函数形式,OOP 不能改变 interface 所实现的成员函数形式,那这样来说,两种实现方法有什么本质的区别吗?既然 C 的 callback 对参数 struct 实现了一种强制转换,为什么就说这种用硬办法的模拟继承比 OOP 的直接书写要优越呢?
    ========================================
    >我2001年在Windows CE试过多种办法,其中也包括command模
    >式。效果不好。我做出来了,但是跟SDK自己的方法相比,显得非
    >常笨拙,除了可以对外宣称“使用了command模式”之外,没有
    >获得任何好处。我觉得这就叫做滥用模式,我是引以为戒的。

    楼主的这种封装我身边已经有很多朋友用过,其中的目的包括学习、应用到实际工程、理论研究等。根据我实践中的理解:实现一个 command 、stragy、state 等结构模式,并没有任何意义,有许多时候可能显得比其他非 OO 的解决方案更笨拙。后来一个老师一言点醒了我,他说:“一些结构模式,是要用在 framework 的层面上,配合设计整个 framework 运作才显得强而有力。我们如果觉得这种模式没用,那是因为我们没用在恰当的地方。在这个例子中,你们觉得装饰模式、状态模式没用,那是因为你们没有设计在一个framework 中。”
    ========================================

    总结:

    不知道楼主的想法为什么这么奇怪,忽略其他所有的因素,单单从调用的 callee 和 caller 关系来看,OO 的 command 模式和 callback 都不能改变调用的形式,本质上是一样的。既然如此,这么还有“C#可以让整件事情在表面上看起来很漂亮,可是骨子里还是邋遢的。”这种奇怪的论调呢?

    Command 模式,真正的优势是作为
    #deavilness 发表于2005-03-11 17:28:00  IP: 202.105.21.*
    ========================================
    >不,Command模式不是一个好的解决方法——否则,为什么没有
    >任何一个大型GUI Framework采用Command模式作为事件处理方
    >法?关键在于,运用Command模式,caller可以把自己的context
    >包装在object里,但是callee却只能调用cmd->execute(),无法把
    >自己的数据传递给execute()。而事件处理不但需要caller的数据,
    >也需要callee的数据。你也许会说,给execute()加一个参数不就行
    >了?不行,因为那样的话,Caller就必须知道callee的类型,紧耦
    >合又产生了 :-(

    不明白楼主为什么有这种奇怪的想法。

    即使是C 语言的 Callback 函数,也不能改变被调用者的 callback function 形式。在参数方面,Windows 的 API 采用了一个比较笨拙的方法,就是传个地址过去,然后强制转换成所需要的类型。而这种方式,用了一种 struct 包含的结构实现了对“继承”的一种模拟。这种 struct 实现的模拟继承,把代码和编译器的物理结构紧紧的联系在一起了。

    既然 C 语言的 callback 不能改变被调用者的函数形式,OOP 不能改变 interface 所实现的成员函数形式,那这样来说,两种实现方法有什么本质的区别吗?既然 C 的 callback 对参数 struct 实现了一种强制转换,为什么就说这种用硬办法的模拟继承比 OOP 的直接书写要优越呢?
    ========================================
    >我2001年在Windows CE试过多种办法,其中也包括command模
    >式。效果不好。我做出来了,但是跟SDK自己的方法相比,显得非
    >常笨拙,除了可以对外宣称“使用了command模式”之外,没有
    >获得任何好处。我觉得这就叫做滥用模式,我是引以为戒的。

    楼主的这种封装我身边已经有很多朋友用过,其中的目的包括学习、应用到实际工程、理论研究等。根据我实践中的理解:实现一个 command 、stragy、state 等结构模式,并没有任何意义,有许多时候可能显得比其他非 OO 的解决方案更笨拙。后来一个老师一言点醒了我,他说:“一些结构模式,是要用在 framework 的层面上,配合设计整个 framework 运作才显得强而有力。我们如果觉得这种模式没用,那是因为我们没用在恰当的地方。在这个例子中,你们觉得装饰模式、状态模式没用,那是因为你们没有设计在一个framework 中。”
    ========================================

    总结:

    不知道楼主的想法为什么这么奇怪,忽略其他所有的因素,单单从调用的 callee 和 caller 关系来看,OO 的 command 模式和 callback 都不能改变调用的形式,本质上是一样的。既然如此,这么还有“C#可以让整件事情在表面上看起来很漂亮,可是骨子里还是邋遢的。”这种奇怪的论调呢?

    Command 模式,真正的优势是作为
    #deavilness 发表于2005-03-11 17:30:00  IP: 202.105.21.*
    ========================================
    >不,Command模式不是一个好的解决方法——否则,为什么没有
    >任何一个大型GUI Framework采用Command模式作为事件处理方
    >法?关键在于,运用Command模式,caller可以把自己的context
    >包装在object里,但是callee却只能调用cmd->execute(),无法把
    >自己的数据传递给execute()。而事件处理不但需要caller的数据,
    >也需要callee的数据。你也许会说,给execute()加一个参数不就行
    >了?不行,因为那样的话,Caller就必须知道callee的类型,紧耦
    >合又产生了 :-(

    不明白楼主为什么有这种奇怪的想法。

    即使是C 语言的 Callback 函数,也不能改变被调用者的 callback function 形式。在参数方面,Windows 的 API 采用了一个比较笨拙的方法,就是传个地址过去,然后强制转换成所需要的类型。而这种方式,用了一种 struct 包含的结构实现了对“继承”的一种模拟。这种 struct 实现的模拟继承,把代码和编译器的物理结构紧紧的联系在一起了。

    既然 C 语言的 callback 不能改变被调用者的函数形式,OOP 不能改变 interface 所实现的成员函数形式,那这样来说,两种实现方法有什么本质的区别吗?既然 C 的 callback 对参数 struct 实现了一种强制转换,为什么就说这种用硬办法的模拟继承比 OOP 的直接书写要优越呢?
    ========================================
    >我2001年在Windows CE试过多种办法,其中也包括command模
    >式。效果不好。我做出来了,但是跟SDK自己的方法相比,显得非
    >常笨拙,除了可以对外宣称“使用了command模式”之外,没有
    >获得任何好处。我觉得这就叫做滥用模式,我是引以为戒的。

    楼主的这种封装我身边已经有很多朋友用过,其中的目的包括学习、应用到实际工程、理论研究等。根据我实践中的理解:实现一个 command 、stragy、state 等结构模式,并没有任何意义,有许多时候可能显得比其他非 OO 的解决方案更笨拙。后来一个老师一言点醒了我,他说:“一些结构模式,是要用在 framework 的层面上,配合设计整个 framework 运作才显得强而有力。我们如果觉得这种模式没用,那是因为我们没用在恰当的地方。在这个例子中,你们觉得装饰模式、状态模式没用,那是因为你们没有设计在一个framework 中。”
    ========================================

    总结:

    不知道楼主的想法为什么这么奇怪,忽略其他所有的因素,单单从调用的 callee 和 caller 关系来看,OO 的 command 模式和 callback 都不能改变调用的形式,本质上是一样的。既然如此,这么还有“C#可以让整件事情在表面上看起来很漂亮,可是骨子里还是邋遢的。”这种奇怪的论调呢?

    Command 模式,真正的优势是作为
    #deavilness 发表于2005-03-11 17:32:00  IP: 202.105.21.*
    ========================================
    >不,Command模式不是一个好的解决方法——否则,为什么没有
    >任何一个大型GUI Framework采用Command模式作为事件处理方
    >法?关键在于,运用Command模式,caller可以把自己的context
    >包装在object里,但是callee却只能调用cmd->execute(),无法把
    >自己的数据传递给execute()。而事件处理不但需要caller的数据,
    >也需要callee的数据。你也许会说,给execute()加一个参数不就行
    >了?不行,因为那样的话,Caller就必须知道callee的类型,紧耦
    >合又产生了 :-(

    不明白楼主为什么有这种奇怪的想法。

    即使是C 语言的 Callback 函数,也不能改变被调用者的 callback function 形式。在参数方面,Windows 的 API 采用了一个比较笨拙的方法,就是传个地址过去,然后强制转换成所需要的类型。而这种方式,用了一种 struct 包含的结构实现了对“继承”的一种模拟。这种 struct 实现的模拟继承,把代码和编译器的物理结构紧紧的联系在一起了。

    既然 C 语言的 callback 不能改变被调用者的函数形式,OOP 不能改变 interface 所实现的成员函数形式,那这样来说,两种实现方法有什么本质的区别吗?既然 C 的 callback 对参数 struct 实现了一种强制转换,为什么就说这种用硬办法的模拟继承比 OOP 的直接书写要优越呢?
    ========================================
    >我2001年在Windows CE试过多种办法,其中也包括command模
    >式。效果不好。我做出来了,但是跟SDK自己的方法相比,显得非
    >常笨拙,除了可以对外宣称“使用了command模式”之外,没有
    >获得任何好处。我觉得这就叫做滥用模式,我是引以为戒的。

    楼主的这种封装我身边已经有很多朋友用过,其中的目的包括学习、应用到实际工程、理论研究等。根据我实践中的理解:实现一个 command 、stragy、state 等结构模式,并没有任何意义,有许多时候可能显得比其他非 OO 的解决方案更笨拙。后来一个老师一言点醒了我,他说:“一些结构模式,是要用在 framework 的层面上,配合设计整个 framework 运作才显得强而有力。我们如果觉得这种模式没用,那是因为我们没用在恰当的地方。在这个例子中,你们觉得装饰模式、状态模式没用,那是因为你们没有设计在一个framework 中。”
    ========================================

    总结:

    不知道楼主的想法为什么这么奇怪,忽略其他所有的因素,单单从调用的 callee 和 caller 关系来看,OO 的 command 模式和 callback 都不能改变调用的形式,本质上是一样的。既然如此,这么还有“C#可以让整件事情在表面上看起来很漂亮,可是骨子里还是邋遢的。”这种奇怪的论调呢?

    Command 模式,真正的优势是作为
    #deavilness 发表于2005-03-11 17:33:00  IP: 202.105.21.*
    ========================================
    >不,Command模式不是一个好的解决方法——否则,为什么没有
    >任何一个大型GUI Framework采用Command模式作为事件处理方
    >法?关键在于,运用Command模式,caller可以把自己的context
    >包装在object里,但是callee却只能调用cmd->execute(),无法把
    >自己的数据传递给execute()。而事件处理不但需要caller的数据,
    >也需要callee的数据。你也许会说,给execute()加一个参数不就行
    >了?不行,因为那样的话,Caller就必须知道callee的类型,紧耦
    >合又产生了 :-(

    不明白楼主为什么有这种奇怪的想法。

    即使是C 语言的 Callback 函数,也不能改变被调用者的 callback function 形式。在参数方面,Windows 的 API 采用了一个比较笨拙的方法,就是传个地址过去,然后强制转换成所需要的类型。而这种方式,用了一种 struct 包含的结构实现了对“继承”的一种模拟。这种 struct 实现的模拟继承,把代码和编译器的物理结构紧紧的联系在一起了。

    既然 C 语言的 callback 不能改变被调用者的函数形式,OOP 不能改变 interface 所实现的成员函数形式,那这样来说,两种实现方法有什么本质的区别吗?既然 C 的 callback 对参数 struct 实现了一种强制转换,为什么就说这种用硬办法的模拟继承比 OOP 的直接书写要优越呢?
    ========================================
    >我2001年在Windows CE试过多种办法,其中也包括command模
    >式。效果不好。我做出来了,但是跟SDK自己的方法相比,显得非
    >常笨拙,除了可以对外宣称“使用了command模式”之外,没有
    >获得任何好处。我觉得这就叫做滥用模式,我是引以为戒的。

    楼主的这种封装我身边已经有很多朋友用过,其中的目的包括学习、应用到实际工程、理论研究等。根据我实践中的理解:实现一个 command 、stragy、state 等结构模式,并没有任何意义,有许多时候可能显得比其他非 OO 的解决方案更笨拙。后来一个老师一言点醒了我,他说:“一些结构模式,是要用在 framework 的层面上,配合设计整个 framework 运作才显得强而有力。我们如果觉得这种模式没用,那是因为我们没用在恰当的地方。在这个例子中,你们觉得装饰模式、状态模式没用,那是因为你们没有设计在一个framework 中。”
    ========================================

    总结:

    不知道楼主的想法为什么这么奇怪,忽略其他所有的因素,单单从调用的 callee 和 caller 关系来看,OO 的 command 模式和 callback 都不能改变调用的形式,本质上是一样的。既然如此,这么还有“C#可以让整件事情在表面上看起来很漂亮,可是骨子里还是邋遢的。”这种奇怪的论调呢?

    Command 模式,真正的优势是作为
    #deavilness 发表于2005-03-11 17:35:00  IP: 202.105.21.*
    ========================================
    >不,Command模式不是一个好的解决方法——否则,为什么没有
    >任何一个大型GUI Framework采用Command模式作为事件处理方
    >法?关键在于,运用Command模式,caller可以把自己的context
    >包装在object里,但是callee却只能调用cmd->execute(),无法把
    >自己的数据传递给execute()。而事件处理不但需要caller的数据,
    >也需要callee的数据。你也许会说,给execute()加一个参数不就行
    >了?不行,因为那样的话,Caller就必须知道callee的类型,紧耦
    >合又产生了 :-(

    不明白楼主为什么有这种奇怪的想法。

    即使是C 语言的 Callback 函数,也不能改变被调用者的 callback function 形式。在参数方面,Windows 的 API 采用了一个比较笨拙的方法,就是传个地址过去,然后强制转换成所需要的类型。而这种方式,用了一种 struct 包含的结构实现了对“继承”的一种模拟。这种 struct 实现的模拟继承,把代码和编译器的物理结构紧紧的联系在一起了。

    既然 C 语言的 callback 不能改变被调用者的函数形式,OOP 不能改变 interface 所实现的成员函数形式,那这样来说,两种实现方法有什么本质的区别吗?既然 C 的 callback 对参数 struct 实现了一种强制转换,为什么就说这种用硬办法的模拟继承比 OOP 的直接书写要优越呢?
    ========================================
    >我2001年在Windows CE试过多种办法,其中也包括command模
    >式。效果不好。我做出来了,但是跟SDK自己的方法相比,显得非
    >常笨拙,除了可以对外宣称“使用了command模式”之外,没有
    >获得任何好处。我觉得这就叫做滥用模式,我是引以为戒的。

    楼主的这种封装我身边已经有很多朋友用过,其中的目的包括学习、应用到实际工程、理论研究等。根据我实践中的理解:实现一个 command 、stragy、state 等结构模式,并没有任何意义,有许多时候可能显得比其他非 OO 的解决方案更笨拙。后来一个老师一言点醒了我,他说:“一些结构模式,是要用在 framework 的层面上,配合设计整个 framework 运作才显得强而有力。我们如果觉得这种模式没用,那是因为我们没用在恰当的地方。在这个例子中,你们觉得装饰模式、状态模式没用,那是因为你们没有设计在一个framework 中。”
    ========================================

    总结:

    不知道楼主的想法为什么这么奇怪,忽略其他所有的因素,单单从调用的 callee 和 caller 关系来看,OO 的 command 模式和 callback 都不能改变调用的形式,本质上是一样的。既然如此,这么还有“C#可以让整件事情在表面上看起来很漂亮,可是骨子里还是邋遢的。”这种奇怪的论调呢?

    Command 模式,真正的优势是作为
    #terry yang 发表于2005-04-08 19:48:00  IP: 222.68.249.*
    感觉C#已经没有C味了。
    #program_net 发表于2007-09-18 10:28:20  IP: 60.178.242.*
    写的不错
    #program_net 发表于2007-09-18 10:28:39  IP: 60.178.242.*
    good
    #jcc3120 发表于2008-05-08 14:44:57  IP: 222.92.2.*
    mark
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 孟岩