现在的位置: 首页 > 综合 > 正文

委托、组件以及表面上的简单性

2013年08月23日 ⁄ 综合 ⁄ 共 6061字 ⁄ 字号 评论关闭

 

以下是转载,转载自:http://blog.csdn.net/lxwde/archive/2006/07/02/865523.aspx

 

本访谈系列的翻译已经征得原作者的同意,转载请保留原作者和译者的链接。

Copyright © 1996-2005 Artima Software, Inc. All rights reserved

Delegates, Components, and Simplexity
A Conversation with Anders Hejlsberg, Part III
by Bill Venners with Bruce Eckel
September 1, 2003

委托、组件以及表面上的简单性

翻译:刘晓伟

摘要
Anders Hejlsberg,C#的主架构师,与Bruce Eckel和Bill Venners谈论了谈论了委托(delegates)以及C#对于组件的概念给予的头等待遇。

Anders Hejlsberg,微软的一位杰出工程师,他领导了C#(发音是C Sharp)编程语言的设计团队。Hejlsberg首次跃上软件业界舞台是源于他在80年代早期为MS-DOS和CP/M写的一个Pascal编译器。不久一个叫做Borland的非常年轻的公司雇佣了他并且买下了他的编译器,从那以后这个编译器就作为Turbo Pascal在市场上推广。在Borland,Hejlsberg继续开发Turbo Pacal并且在后来领导一个团队设计Turbo Pascal的替代品:Delphi。1996年,在Borland工作13年以后,Hejlsberg加入了微软,在那里一开始作为Visual J++和windows基础类库(WFC)的架构师。随后,Hejlsberg担任了C#的主要设计者和.NET框架创建过程中的一个主要参与者。现在,Anders Hejlsberg领导C#编程语言的后续开发。

2003年7月30号,Bruce Eckel(《Thinking in C++》以及《Thinking in Java》的作者)和Bill Venners(Artima.com的主编)与Anders Hejlsberg在他位于华盛顿州Redmond的微软办公室进行了一次面谈。这次访谈的内容将分多次发布在Artima.com以及Bruce Eckel将于今年秋天发布的一张音频光碟上。在这次访谈中,Anders Hejlsberg谈论了C#语言和.NET框架设计上的一些取舍。

·        在 第一部分:C#的设计过程中, Hejlsberg谈论了C#设计团队所采用的流程,以及在语言设计中可用性研究(usability studies)和好的品味(good taste)相对而言的优点。

·        在第二部分:Checked Exceptions的问题中, Hejlsberg谈论了已检测异常(checked exceptions)的版本(versionability)问题和可伸缩性(scalability)问题。

·        在第三部分里,Hejlsberg 谈论了委托(delegates)以及C#对于组件的概念给予的头等待遇。

简单(Simplicity)vs.表面上的简单(Simplexity)
Bill Venners: C#与Java的一个不同之处是它向感兴趣的对象传播事件的方式。Java使用实现了listener接口的类(通常是内部类)。C#使用委托(delegates),更有点像函数指针。为什么要选择委托呢?

Anders Hejlsberg: 让我先说说通常我是如何看待简单性(simplicity)的。从来没有人争论说简单不好,但是人们给简单下的定义千差万别。有一种简单性(simplicity)我喜欢叫做“表面上的简单(simplexity)”。当你试图把一些极其复杂的东西包裹(wrap)到相对简单的东西里的时候,通常你只是隐藏了(shroud)复杂性。实际上你并不是在设计一个真正简单的系统。从某种意义上说你把它弄得更复杂了,因为现在用户必须弄明白你省略掉了哪些东西而说不定什么时候他们又需要用上。这就是“表面上的简单(simplexity)”。对我来说,简单性必须是真正意义上的,也就是说你越往下探究它就越简单。而不应该是你越深入探究它就越复杂。

委托(Delegates)vs.接口( Interfaces)
Anders Hejlsberg: 委托添加了一种类和接口所没有的表达方法,这也是为什么我认为它们是重要的。走在我们前面的那些编程语言意识到了它们的重要性。它们有许多名称:函数指针,成员函数指针。在LISP里它们被叫作闭包(closures)。当归结为一点的时候,它们就是函数式编程(functional programming)的全部。它们非常有用。

Bill Venners: 怎么有用呢?

Anders Hejlsberg: 实际上你可以用接口来做委托可以做的事情,但是你得做很多例行公事性质的事情。举个例子,让我们看看你在Java里和.NET世界分别是如何处理事件的。因为Java里没有委托,所以你最终选择使用接口。

你定义一个接口用以代表你的所有事件。这个接口可以声明一个、两个、三个、四个方法,或者更多。好了,现在有一个问题。如何结构化它们并不十分清楚。你要为自己所分发的(outgoing)事件准备多少个接口?你是要每个事件一个接口呢还是要所有事件都用一个接口?没有人提供明确的指导,而且有时候它会在某些地方陷入中间状态。现在,为了处理由组件(component)所产生的事件,你必须实现这个接口。当然如果你想要处理来自不同组件的同一组(set)事件,你必须得实现这个接口两次,而这是办不到的。这种情况下你需要创建一个适配器(adapter)。这么一来那些例行公事性质的事情就开始在你面前晃悠了。

使用内部类可以减少一些繁文缛节,但是尽管如此,使用接口还有一个问题就是事件的接受者必须知道他在接受事件。他必须显式地实现listener接口。与此形成对比的是,使用委托只要签名(signature)一致,你就可以把它们对接在一起(slot together)。处理事件的人不需要关心他是如何被调用的。这只不过是个方法(method)罢了。

Bruce Eckel: 有点弱类型化(weaker typing)的意思。

Anders Hejlsberg: 是的,实际上它就是。

Bruce Eckel: 也就是说它更灵活了。

Anders Hejlsberg: 是的,确实如此。它完全取决于你是否有一致的签名(signature),也就是参数列表。如果你有一致的参数列表,你就可以把它们捆绑在一起。而且从概念上它完全符合最终用户对于回调(call back)的期望,对吗?给我一些参数,然后我(用它们)写一些代码。对我来说听起来更像是一个方法。抱歉,我是想要给你一个关于那个方法的引用,这实际上就是委托。

Bruce Eckel: 而且最终你并没有丧失类型检测。类型检测是在运行时刻做的,对吗?

Anders Hejlsberg: 不,更多情况下是在编译时刻。当构造一个delegate的时候,你会得到C++程序员可能称之为绑定的成员函数指针的东西。Delegate引用特定对象的一个方法。如果那个方法是虚函数,你可以准确地找出需要的是哪个函数。所以从某种意义上来说,在delegate被构造的时候就你可以确定是哪个虚函数。通过delegate所完成的调用从字面上看只不过就是一个间接的调用指令。

Bruce Eckel: 其它地方并不需要间接调用了。

Anders Hejlsberg: 你说的对,你可以在构造delegate的时候一劳永逸地解析出虚函数表(VTBL)的间接调用,以后每次通过delegate调用的时候就可以直接找到那个方法。所以说,委托不仅仅比接口分派(interface dispatch)效率更高,而且它们也可能比常规的方法分派(method dispatch)效率高。

Bruce Eckel: C#还有组播委托(multicast delegate),也就是说一个delegate可以触发多个函数被调用。它是一个正交(orthogonal)特性吗?

Anders Hejlsberg: 组播(Multicast)是一个完完全全的正交特性。说实话,我对组播是否是非常好的东西持中立的态度。我认为确实有用得着它的地方,但是我也觉得我们应该保守一点认为所有的delegates都是单播的(single cast)。有些人发现多播非常重要,而且它在一些地方工作的很好,但是绝大多数情况下委托都是单播的。实际上,我们把系统构建成了只有在你使用多播的时候才需要为它付出一定的代价。

Bill Venners: 您刚才说的简单(simplicity)和表面上的简单(simplexity)如何适用于委托呢?简单性在哪里?表面上的简单又在哪里?

Anders Hejlsberg: 如果你用接口来模拟委托,那你最终会陷入繁文缛节和一大堆适配器里。实际上,看看任何捆绑JavaBeans的工具就知道了。它们产生一大堆适配器然后告诉你,“不要改动下面这写代码。我们会为你产生这些古怪的辅助类。”我认为,这就是表面上的简单。整个系统不是真正意义上的简单,实际上非常复杂,但是如果你只是瞄一眼的话看起来是很简单。

组件是头等的概念(Components are First-Class)
Bill Venners: 在公布在O’Reilly网络上的一篇访谈中,为了说明C#对于属性(properties)和事件(events)的支持是合理的,你说道,“现今开发者都在构建软件组件(components),而不是自成一体的应用程序或者类库。每个人都是在构建新组件,而新组建继承自由宿主环境所提供的某些基础组件。这些组件覆写(override)某些方法和属性,处理一些事件,然后再把组件放回去。把这些概念当作first classs是很重要的。”

我希望能更好地理解你这段话的意思,因为我一直认为自己是在构建类,而不是组件。你指的是为了让其他人以Delphi、Visual Basic或者JavaBeans的方式连接到一起而构建组件的人们?你说的组件是这个意思吗?

Anders Hejlsberg: 组件(component)这个词最大的好处就是你可以拿它来到处忽悠,而且它听上去也很棒,但是我们所思考的并不是同一个东西。最简单的形式,提到组件的时候我的意思是一个类再加一些东西。组件是一个自包含的(self-contained)软件单元,不仅仅是代码和数据。它是一个通过属性(properties)、方法和事件来暴露自己的类。它是一个有额外attributes与它关联的类,这些attributes的形式是元数据(metadata)或者naming patterns或者随便其它什么形式。这些attributes提供一些动态的额外信息,诸如组件是如何嵌入一个特定的宿主环境、它如何让自己持久化——所有你想通过元数据进行说明的额外的东西。通过元数据,IDE可以智能地推断出某个组件是干什么的然后显示给你关于它的文档。组件把所有这些都整合起来。

Bill Venners: 当使用Java的时候,我觉得是我是在设计类库,而不是组件库,可能是因为get和set太不优雅了。我确实使用了get和set,而且我的确也触发事件(fire events),但是我原本并没有打算让这些类在一个Bean构建器的IDE里使用。我想象中它们应该被那些手写代码的人使用。所以我仍然怀疑有多少人在实际上写类似于JavaBean的组件以及这是否是大势所趋,因为依我自己的经验我并没有见到很多。

Anders Hejlsberg: 现今主流的面向对象编程语言都是混血儿。它们有许多结构化的编程方法在里面。对象在很大程度上还是添加了一大堆方法和一个this指针的结构(structs)。我想,从概念上来说,当你想到一个对象或者一个组件的时候,它们绝对应该有属性也绝对应该有事件。给编程语言里的这些东西头等待遇可以让一切更简单。

人们可能会争论说C#对于属性和事件的支持只不过是语法糖衣(syntactic sugar)罢了,但是所有的东西不都是语法糖衣吗?对吗?对象也只是语法糖衣。我们可以自己弄一个虚函数表(VTBL),用C里面的宏(macros)就可以了,不是吗?毫无疑问,你可以用C写出面向对象的程序。只不过是非常复杂罢了。类似地,你可以用C++或者Java写组件,但是因为核心概念(core concepts)在这两种语言里没有作为第一等(first class)的东西,所以你最终还是得借助于别的东西。这里又说到了这个词(指first class)。就properties来说,它们并不是真正意义上的properties,它们是getBla和setBla。但是当它们在属性检视器里显示出来的时候,它们是bla。你只需要知道那里有一个映射(mapping)就可以了。

很明显,组件是一种趋势。我们就是以这种方式使用类的,但是在大多数我们与组件打交道的语言里,它们并没有作为头等的概念。我只是想说它们应该成为头等的概念。

我们谈论PME编程模型——属性(properties)、方法(Methods),事件(events)——已经有很长一段时间了,而且我们在日常编程中都使用过它们。为什么我们不实实在在地在编程语言里给它们头等的待遇呢?

下周
Anders Hejlsberg访谈的下一部分将会在(2003年)9月15号,星期一贴出来。如果你想收到Artima.com上新文章每周简报的电子邮件,请订阅Artima Newsletter。

反馈
对本文所描述的设计原则有自己的观点么?那么请到News&Ideas论坛讨论这篇文章Delegates, Components, and Simplexity。

资源
深入C#:微软主架构师Anders Hejlsberg访谈:

http://windows.oreilly.com/news/hejlsberg_0800.html

A Comparative Overview of C#:
http://genamics.com/developer/csharp_comparative.htm

Microsoft Visual C#:
http://msdn.microsoft.com/vcsharp/

Anders Hejlsberg不是Artima的采访对象中第一个提到品味的。Jim Waldo在他的访谈中针对构建一个由有品味的程序员组成的团队给出了几乎同样的评述:

http://www.artima.com/intv/waldo10.html

Ken Arnold’s的访谈有一整部分都是关于设计品味的——品味和美学(Taste and Aesthetics):
http://www.artima.com/intv/taste.html

 

抱歉!评论已关闭.