Bjarne Stroustrup谈系统设计的原则和方法
来源: 作者: 出处:综艺读书 2006-09-25Bjarne Stroustrup访谈录
作者:Bill Venners
译者:redguardtoo
原文网址:http://www.artima.com/intv/elegance.html
译者简介:
全文共分四部分。
|
|
|||
第二部分,第三部分谈了程序设计的风格问题,笔者认为其中关于类的设计的讨论可以说是一针见血。任何有志于面向对象程序设计的高级程序员(无论使用何种语言开发)都应该读一读这部分。
第四部分谈了抽象和效率的问题。其中一个重要观点就是,抽象有利于效率而不是反之。
全文:
在2003年9月的JAOO会议上,Bill Venners和Bjarne Stroustrup碰面并进行了这次谈论。
Bjarne Stroustrup是C++语言的发明人。
0. 精致以及其他设计理念(Elegance and Other Design Ideals)
Bjarne Stroustrup谈论了软件设计的许多方面。包括如何将小的软件扩展为大的软件,避免在设计者和用户之间区分类,过早一般化(generalization)的危险和精致(elegance)的本质等等。
0.1. 编码之前思考(Thinking Before You Code)
Bill Venners: 在和Biltek的谈话中,你说过:“我不是使用支持工具进行巧妙设计的信徒,但是我强烈支持系统地使用数据抽象,面向对象编程,和generic programming。不拥有支持库和模板,不进行事先的总体设计,而是埋头写下一页页的代码,这是在浪费时间。这是给维护增建困难。”你认为进行多少事先的设计合适?编码之前我们该思考多长时间?
Bjarne Stroustrup: 取决于问题的规模。如果你今天下午就要使用这个程序,使用信封背面做做设计就可以了。如果你的系统需要多年才能完成,那你当然需要更多的事先设计。项目需要的人越多,需要进行越多的设计工作。然而,系统越大,事先的设计越困难。设计工具不能给你很多的反馈,所以我认为建立一个更小的系统,慢慢扩展更好一点。有一个基本原则,每一个成功的大型项目都是由小项目扩展而来的。每个小项目又是由更小的项目扩展而成的。依此类推。
有些人认为我说的是建立原型。某种程度上是的。但不全是。原型有时候可能是个陷阱。如果原型是由完全不同的开发者使用不同的工具开发出来和真实的应用程序不同的东西,你就会有麻烦。例如,相对于开发面向10000个客户的真实应用程序,你可以用更好的软硬件加上更好的程序员开发面向10个客户的原型。你可以忽略一些非标准的问题。你可以忽略兼容性问题。最后你发现,原型得到的方案无法应用到更大规模的实际应用程序上。
有时候你可以先实现系统的部分功能。但我强调尽可能早地进行集成测试。例如,写个简单的“hello world”程序。在分布式系统上,你就为分布式系统的每台电脑都写个程序,然后让它们交谈。于是你发现Java ORB不能和你的C++ ORB交谈,或者你的在sun机器上的java虚拟机不能和HP机器上java虚拟机交谈。当然我只是举例。但是可以肯定的是,“总”会有未料到的问题发生。我不是在谈原型。我在谈真实环境下的真实系统的试验。尽可
能早的进行这些试验。
0.2. 用库思考(Thinking in Libraries)
Bill Venners: 我经常听你宣称C++支持库的设计。哪种程度上应用程序开发者以可以认为自己是开发库呢?我们需要把应用程序分成这个库或者那个库吗?或者你说的库就是字面意义上会给很多人使用的库?
Bjarne Stroustrup: 我认为人们应该把编程分成库的开发和库的使用两步。今天你写支持库,明天你使用它。但是人们很多时候不这样做。即使我一个人写一个很小的程序。我也总是先写一些支持类和支持函数。我不喜欢直接开始写一个完整的应用程序。所以,不管你是写应用程序还是写库,你都需要划分模块。
C++的一个问题是有太多的库,但是没有一个大卖场有所有这些库。C++不是对GUI支持不好。C++有GUI库。问题是C++有25个GUI库。有些GUI库不错。但是人们说:“可是C++没有标准GUI库。”Python不一样。人们知道到哪里去找Python的GUI库。所以C++的问题是有太多库,但是所有的库市场宣传都做的不够(It′s a problem of riches, plurality, and alack of marketing)。搞C++的看来都很穷,没有钱来提供一个可以找到所有库的大卖场。
绝对不能认为自己已经掌握了完美的库的设计艺术。抱着这样的态度去设计库,一定会失败。在我开始使用你设计的库后,你认为大功告成,于是拍拍屁股走人。这可不对。库的设计者必须是库的使用者,或者至少,设计者必须长期维护库。和用户长期交流,你才能知道什么是正确的抽象,什么是正确的细节。库需要演化。最好的库是由库的使用者设计的。类的使用者和设计者是两拨人,这可不对。
0.3. 哪些纳入语言标准,哪些放弃(What to Leave In, What to Leave Out)
Bill Venners: C++内容很多。语言或者库的内容越多,语言或者库的使用者越得心应手,但是使用者必须学习的东西也多。即使为了知道哪些东西可以忽略,使用者们也必须学习很多东西。作为C++语言和标准库的设计者,你是如何决定哪些特性放进标准,哪些忽略的呢?
Bjarne Stroustrup: 这是很难决定的。我没有一种足够好的哲学来做决定,我想别人也没。在C++语言中,我试着把对所有人而不是少数人有益的特性放进标准。我试图放进标准的是一些通用的工具。例如,我不把GUI特性放进标准。因为很多程序没有GUI界面。我不试图增加对数据库的标准支持。因为许多人并不使用数据库。货币也不作为语言特性,因为你可以使用支持货币的库。我尽可能使语言简洁,避免冗余,避免人们学习太多的东西。我在模板(template),内联(inline),重载(overload)方面做的工作,消除了冗余,消除了危险的强制类型转换。这是最好的例子。
当然,我刚才说的既可以适用于标准库的设计,也适用于语言的设计。很难简单地在库和语言之间画一条线。我总是试图把一些能够实现抽象机制的特性加入C++语言。所以和别的一些语言不同,我没有将advanced vector加入语言特性中,因为我可以在库中实现该特性。我没有提供一些操作字符串的工具,但是我提供了一些抽象机制,可以在此基础上建立字符串类。我没有提供属性(properties),因为你可以自己实现属性类。简单的说,我反对现在语言设计的一些流行趋势,这些语言把一些具体的和只用于某些特定场合的工具也加入语言本身。这是我个人的设计理念。
在我的书《The Design and Evolution of C++》中,我详细讨论了我的设计理念。阅读这本书可以使你避免某些人(直接说,就是我)常犯的错误,例如事后诸葛亮,试图亡羊补牢啦等等。我的书中诚实地记录了我在设计C++期间的所有想法,包括我犯的所有错误。很不幸的是,计算机界的历史是常常是修正主义者(revisionist)的历史。但是我不是修正主义者。C++的标准库和使用风格有过变化,但是语言本身没有改变。
0.4. 防止自我伤害(Protecting People From Themselves)
Bill Venners: 语言和库的设计者通常想的是避免使用者自我伤害(protecting users from themselves)。但是你设计C++的哲学似乎是给C++的使用者最大的灵活性和方便,即使这种灵活和方便会导致他们自我伤害。在你的C++ FAQ中,你写道,“(作为语言设计者)你如果试图保护使用者避免一些简单明显的错误,你就会间接地给他们制造了新的和不明显的错误。”那么你认为语言设计者应该怎么做呢?
Bjarne Stroustrup:某些语言设计者把使用者当作未成年的小孩子。我不会这样做。也许我是有点过于浪漫了。我认为程序员比一般的计算机用户聪明。我认为程序员是值得尊敬的专业人员。
此外,我认为语言的设计者有意地限制程序员实现一个任务的选择权是剥夺了他们的公民权利。我经常看到用户由于想要实现被系统限制的功能而不得不去求系统的供应商。最好的例子就是某些第四代语言和一些所谓能从模型或者图中产生代码的工具。在这些例子里,如果你要用到某种特性,而你的开发工具没有提供这种特性,你就没有办法了。你能做的就是求工具的供应商在下一个版本中增加新的特性。我看到的最过分的例子就是一个用户竟然不能使用自己定制的排序(sort)。在这些语言中,你当然也不能用语言本身写标准库或者更先进的库。于是你把语言的开发者分成了两类。一类是不被信任的普通开发者。一类是拥有开发库的特权的高级开发者。当然不用奇怪的是,后者都是为供应商工作的。
我认为人都是平等的。我的理想就是如果你不喜欢随语言提供的库,你就可以用语言自己写一个。语言本身保证了你的自由选择权。当然那些靠语言赚钱的供应商是不会喜欢我的理想的。
C的设计原则就是你可以用C语言实现标准库。C++的原则也是如此。别的语言是否有这样的原则就难说了。别的语言用C或者C++实现语言的标准库。这种做法也说的过去。但是这样就存在风险。这个风险就是,使用语言的用户变成了低级使用者,他们被所谓的语言专家控制,而这些专家则使用C或者C++完成实际的工作。这些专家都是供应商的人。如果你使用的语言具有通用性(generality),你可以获得安全。免于被供应商控制的安全。
0.5. 为无法想象设计(Design Beyond Imagination)
Bill Venners: 你和Rogue Wave说过,“我所创造的工具,应该能做我无法想象的事情。”
Bjarne Stroustrup: 是的。
Bill Venners: 怎么做到这一点
Bjarne Stroustrup: 听。从很多人那里听,然后追求通用性(generality)。
Bill Venners: 通用性(generality)指的是对具体问题的抽象解决方案吗?或者是很多人都要使用的工具?请定义通用性(generality)。
Bjarne Stroustrup: 让我举例说明。类(class)可以做任何事。C++没有为大的对象,小的对象,面向对象的类(object-oriented classes),值类型(value types),GUI事件(GUI events),属性(Properties),线程(threads)等等分别定义类的概念。类就是类。C++的类的概念适用于各种场合,并且有足够的效率。“因为使用类是昂贵的(expen
sive),所以类的概念只适用于大的昂贵的操作(big expensive operations)。”,这不是我的设计。(译者按:本句很难翻译,我的理解是Bjarne Stroustrup的理念是,类的概念必须有通用性,为此他确保类是有效率的。全文为“I didn′t decide that classes should be only for big expensive operations because it′s expensive to call them
.”)
通用性(generality)不仅仅是指不限制用户。通用性(generality)还有数学的意义。你确保所有的例子都能工作。所有的逻辑设计空间(logical design space)都被覆盖。你说语言必须能做这五件事,不需要更多了。为什么是五?我们都知道,你设计时写下的待实现功能清单永远是不全的。在开发过程中,你总会发现你必须做第六件事情。例如,
C++没有对事件系统(event system)的内建支持,但是C++t的通用机制可以使你实现任何操作系统下的事件系统(event system)。
0.6. 过早的通用(Premature Generalization)
Bill Venners: 现在让我们回到使用库开发应用程序的程序员。他们何时该使用通用工具解决解决一个具体问题呢(与此相对应的是为特定问题写下特定的代码)?
Bjarne Stroustrup: 我不知道。很难泛泛而谈。我只能回答“看情况而定”。我个人一般倾向于在有多次重复的经验前先建立具体的案例。因为人的本性如此。如果我第二次碰到相似的问题了,我会说,“等等,我解决过这个问题”。我已经有了这个对这个具体问题的经验和教训,于是我开始考虑是否能够有个比较抽象的解决方案。有些不成熟的设计者的做法相反,在获得一个具体案例的经验前就试图给出一个通用方案。
Bill Venners: 听起来象是过早的通用(premature generalization)。
Bjarne Stroustrup: 对,就是这样。过早的通用,就如过早的优化。
0.7. 丑陋的语法对应丑陋的操作(Ugly Syntax for Ugly Operations)
Bill Venners: 在你的(C++ Style and Technique FAQ),你说过,“丑陋的操作必须要用丑陋的语法来表达”,我认为这种设计方法很有趣。你不鼓励但是不限制某种做法,于是你就用丑陋的语法来表达这种操作。
Bjarne Stroustrup: 对。这种丑陋的操作就是类型转换(cas)t。Cast是必须的。在C++中,编译器可以对不安全的cast进行检查。相对于C是一种改善。我有意把语法设计的难看点,因为cast本身是丑陋的不安全的操作。
0.8. 精致以及其他设计理念(Elegance and Other Design Ideals)
Bill Venners: 当我们进行设计时,我们的设计理念和设计目标应该是什么?为什么?你一直谈到精致(elegance)。投资精致(elegance)的商业回报是什么?或者说你认为设计的目的是什么?
Bjarne Stroustrup: “精致的(elegant)”和“简单的(simple)”是紧密相关的两个词。“易于理解的Understandable)”也是他们的近义词。这些词意味着什么?这些词意味着你可以使用工具。你可以优化你的程序。你可以维护你的程序。你可以移植你的程序。你可以从你的程序中分离出逻辑单元,单独处理它。如果你的程序只是由一大堆“烂糊
面”代码组成的,你就不可以对你的程序做任何事情。
顺便提一下。我认为“可宣言的(declarative)”,就是最精致(elegant)的特性之一。这是我喜欢静态类型语言(statically typed languages)的理由之一。你可以说:这是一个双精度浮点数矩阵。于是很多东西都明了了。你明白这里的乘法是矩阵乘法而不是普通的数值乘法。所有关于矩阵的理论都适用于你宣称的矩阵类型。你声明(declare)一个拥有构造函数(constructor)和析构函数(destructor)的类,然后你构造对象,然后你宣称资源将会在析构函数(destructor)中被释放。非常清晰。不管是对机器还是对人来说都非常清晰。当我使用精致(elegant),...
Bill Venners: 这里的精致(elegant)是什么意思?
Bjarne Stroustrup: 很难说清楚。当你看到数学中的证明时,你可以说这个证明是精致的(elegant),清晰(clear),通用的(general),短小的(short)。我以前学的是数学。精致对我来说是有一种被神圣的光辉照耀的感觉。它是一种美。美是和人的需求有关系的。例如可维护性和可快速开发性。因为你是在比较高的抽象层面构建程序,你可以比较高效地开发程序。
我总是告诉我的学生,必须懒惰。我讨厌很长的程序,因为实际工程中你不会有足够的时间写长的程序的。精致的程序是短的。使人们惊讶的是,如果你把好的C++代码和同等水平的别的语言比较,你会发现C++更短。当你使用标准库或者别的库写C++代码时,你得到的是短的代码,因为你可以简洁地(succinctly)表达你的思想。这就是我的理想。说你想说的。清晰地说。尽可能通用地说。于是代码短而快。
--
Of the Customers, By the Customoers, For the Customers
<a href="http://www.d2ksoft.com>D2KSoft</a>
Our Product:
Mass Email Addin for Outlook --CloneMail
http://www.d2ksoft.com/clonemail
相关图文阅读
频道图文推荐
相关专题
·系统优化大全 (13909篇文章)
·系统安全设置 (18705篇文章)
·系统安装手册 (16385篇文章)
·系统备份专题 (13518篇文章)
·系统维护手册 (13057篇文章)
·系统解决方案 (2041篇文章)
·系统安全设置 (18705篇文章)
·系统安装手册 (16385篇文章)
·系统备份专题 (13518篇文章)
·系统维护手册 (13057篇文章)
·系统解决方案 (2041篇文章)
·帮你远离失业困扰的十大软件技术 (0次浏览)
·习惯必须延续 必要可以延伸 (29次浏览)
·专访SupeSite/X-Space研发经理李国德 (7次浏览)
·帮你远离失业困扰的十大软件技术 (0次浏览)
·蔡文胜讲经:经营个人网站“五部曲” (0次浏览)
·专访SupeSite/X-Space研发经理李国德 (7次浏览)
·帮你远离失业困扰的十大软件技术 (0次浏览)
·蔡文胜讲经:经营个人网站“五部曲” (0次浏览)
·设计师的生活态度和侦探 (85次浏览)
·习惯必须延续 必要可以延伸 (29次浏览)
·专访SupeSite/X-Space研发经理李国德 (7次浏览)
·帮你远离失业困扰的十大软件技术 (0次浏览)
·蔡文胜讲经:经营个人网站“五部曲” (0次浏览)
·习惯必须延续 必要可以延伸 (29次浏览)
·专访SupeSite/X-Space研发经理李国德 (7次浏览)
·帮你远离失业困扰的十大软件技术 (0次浏览)
·蔡文胜讲经:经营个人网站“五部曲” (0次浏览)
最新技术文档
·帮你远离失业困扰的十大软件技术 06-27
·蔡文胜讲经:经营个人网站“五部曲” 06-12
·专访SupeSite/X-Space研发经理李国德 06-09
·习惯必须延续 必要可以延伸 06-01
·设计师的生活态度和侦探 05-15
·七种武器——.NET工程师求职面试必杀技 03-30
·最令我难忘的Java学习经历 03-13
·关于提高自己JAVA水平的十大技术 03-12
·社区精神如何有效的宣扬 03-09
·从程序员到CTO所要培养的六种能力 03-02
·蔡文胜讲经:经营个人网站“五部曲” 06-12
·专访SupeSite/X-Space研发经理李国德 06-09
·习惯必须延续 必要可以延伸 06-01
·设计师的生活态度和侦探 05-15
·七种武器——.NET工程师求职面试必杀技 03-30
·最令我难忘的Java学习经历 03-13
·关于提高自己JAVA水平的十大技术 03-12
·社区精神如何有效的宣扬 03-09
·从程序员到CTO所要培养的六种能力 03-02
站内各频道最新更新文档
站内最新制作专题
|
|||
| ·ACDSEE专题教程-下载使用 ·迅雷专题教程-下载使用 ·Windows XP频道 ·Windows Vista频道 ·Windows 2000频道 ·win2003频道 ·Freebsd频道 ·Oracle频道 |
·Linux频道 ·Windows频道 ·邮件服务器专题 ·协议大全 ·数据恢复指南教程 ·FreeBSD使用教程 ·Linux数据库宝典 ·Linux基础知识 |
||
热门关键字导读
站内频道文章精选
| · 秘密:Vista隐蔽的动态屏保 · 腾讯开发新电子宠物--QQ熊 · 惠普否认2999元PC有价无货 |
· 驱逐Win系统“流氓”文件 · WinXP中获取未使用的IP地址 · 尝试format C:格式化硬盘? |
| · 在DOS下恢复回收站中的文件 · 拯救WinXP崩溃的救命稻草 · Linux系统中超级权限的应用 |
· 搜狗PK谷歌:谁能代言拼... · 昨日重现,一键GHOST轻松.. · 实现Web迅雷在空闲时杀毒 |
| · AVIFile函数制做AVI文件 · VC中链接动态链接库的方法 · 熊猫烧香核心源码(Delphi) |
· DateDiff函数祥解 · JavaScript去除空格的三种 · js效果 图片加载进度实时.. |
| · SQL Server数据库优化方案 · Oracle的初学者入门心得 · JSP连接Mysql数据库 |
· Photoshop为美女做艺术处理 · 用Freehand创建发光字特效 · 设计自己的个性QQ动态表情 |
百度推荐,商机无限
搜索您感兴趣的内容




