软件框架设计的艺术[试读]
***
读者也许会想:“在程序开发领域中,讲述软件设计的技术图书是不是太多了?”,的确如此,因而你有理由来质疑,为什么我还要写一本这样的书而你又凭什么还要再读这样一本书?说起软件设计的经典图书,那本由GoF执笔的《设计模式》,对每一个想要掌握面向对象技术的开发人员来说,已经成为案头必备之书。此外,对于不同类型的应用开发,也存在大量专业的软件设计模式图书。还有Effective Java,这本传世之作已经成为众口相传的Java程序开发圣经。基于以上事实,还有必要再多一本关于软件设计的图书吗? 我相信这自有其必要性。从1997年开始,我一直从事NetBeans的API设计工作。在此期间,与其他设计框架... 查看全部[ *** ]
API设计的特殊所在
为什么说市场上现有的设计图书还不够用呢?这是因为设计框架或者通用类库是一件非常复杂的事情,其复杂度与自行设计内部系统不可同日而语。打个比方,在一台服务器上基于一个小型数据库来搭建一个Web应用之类的小系统,就和盖一间房子差不多。当然,有些房子可能很小,也有些房子会很大,有时也许是一座摩天大楼。这些建筑通常情况下都只有一个主人,只有他才会改造这个房子。如果需要的话,改一下屋顶,换上新窗户,也许会砌面墙多隔出一间来,再拆旧墙打通两个房间,等等。当然,有些改变算不上什么麻烦事,如换个屋顶不会对地板造成什么大的破坏,换个窗户,只要大小规格不变,也不会影响别的部位。但是,如果想把窗户从小变大,就不那么简... 查看全部[ API设计的特殊所在 ]
读者对象
如果此时你正在书店面对这本书,在买与不买之间犹豫不决,那是因为你无法判断这本书对你是否有用。老实说,这点我帮不了你,因为我不是你。但我可以告诉你我自己为什么需要这本书,以及我写作该书的缘由,这样也许可以帮助你决定是否应该购买此书。我在设计NetBeans框架的API时,就像在一片迷茫中寻找光明,总是摸不清方向。最开始,我完全凭直觉,而且认为写API是一种艺术。我知道对于艺术来讲,需要创造力,但设计API,与艺术是不同的范畴。时间慢慢过去,我从已经完成的工作中汲取经验,逐渐整理出一整套思路和度量标准,借助于这些可量化的标准,可以将一个普通的API优化成一个优秀的API。 本书介绍了NetBea... 查看全部[ 读者对象 ]
这本书只适用于Java
NetBeans是一个使用Java语言开发的IDE框架,我的大部分与API有关的知识都是从这个项目中学到的。如果由我来回答这个问题:“这本书是否有益于那些非Java的开发?”那么答案仍然是肯定的。对于如何评价API设计是否良好,本书给出了很多准则,这些准则同样适用于其他的编程语言。本书中的一些议题,例如:开发API的原因,编写具有良好结构的文档的规则和动机,还有那些关于向后兼容的原则。这些内容都可以适用于多种编程语言,包括C、FORTRAN、Perl、Python和Haskell①。 当然,涉及细节的时候,就不得不提到Java语言的具体特性。要知道,Java首先是一种面向对象的语言。为面向对... 查看全部[ 这本书只适用于Java ]
学习编写API
毫无疑问,肯定有不少人用正确的方式开发了很多API,否则现在的市场上就不会有这么多非常有用的软件产品。但设计原则、设计API的技巧及要点,通常都是在开发过程中下意识积累而得,而这一过程往往并不具有借鉴意义。很多设计师往往没有知其所以然就做一些API设计上的决策。结果就是在不停地尝试,犯错,再尝试再犯错,周而复始才逐渐在其潜意识中形成了设计API的相关知识,耽误了很多时间。这一过程中会产生很多指导人们正常做事的技巧,虽然这种过程非常有用,但因为它自身存在的问题,导致其产生的大量技巧非常分散,不易收集和管理。首当其冲的问题就是,这些技巧都有其特定的背景和作用域。很多人都知道,有大量的技巧,对于某一... 查看全部[ 学习编写API ]
这是一本备忘录吗
决定要以何种风格来撰写本书无疑是一件非常困难的事情,我当时在两种完全不同的写作风格之间摇摆不定,无法定夺。一种写作风格是:用非常科学化、公式化的方式来说明API设计时的动机、原因及步骤。使用这种方式来撰写的话,书中给出的建议和规则具有通用性,可以应用于任何项目。当然,通用性是本书的一个目的,书中所说的内容必须是普遍适用的,而不是简单地描述NetBeans项目的10年发展史。而另一方面,我坚信,如果只是在不停地说着一些建议,讲述着这些原则性的内容,而不给出合适的诠释,那么再好的建议也不能起到应有的作用。我不喜欢只说上一堆“是什么”,而不去详细地解释“为什么”。我一直想清楚地分析上下文,并以此来评... 查看全部[ 这是一本备忘录吗 ]
***
软件开发的历史很短,从有人编写和执行第一个计算机程序至今,也不足百年。尽管历史并不悠久,但其影响力并不逊于其他任何一种开创性的发明。有人把计算机科学发展史与人类认识真实世界的历史放在一起加以比较,这非常有意思,我们也借此来理解为什么软件开发需要优秀的API。下面我们来试试这么做。... 查看全部[ *** ]
1.1 理性主义,经验主义以及无绪①
在文艺复兴时期,现代科学产生了两大重量级理论,表现在哲学方面则为理性主义和经验主义。其中理性主义认为理智是信息的首要来源,并给出一个假设:只需要通过思考就能够理解和描述这个真实的世界。理性主义的支持者包括现代科学的众多先驱,像法国哲学家、数学家勒内•笛卡儿(René Descartes,1596—1650),德国数学家戈特弗里德•威廉•莱布尼茨(Gottfried Wilhelm Leibniz,1646—1716),还有泛神论的创始人斯宾诺莎(Benedict Spinoza,1632—1677)。 理性主义可以说是源起于伽利略②的自由落体实验,该实验证明了无论物体的重量如何,其下落的速度... 查看全部[ 1.1 理性主义,经验主义以及无绪① ]
1.2 软件的演变过程
在20世纪40年代和50年代初时,编写代码是一件非常困难的事。人们不得不学习机器语言,同时还要知道寄存器的大小和数量,有时候,事情不妙,还要拿起螺丝刀亲自上场①,去连接计算单元的信号线。人们的主要精力不在于思考一个算法,而放在将算法编写成可执行程序上,这是一种枯燥又机械的工作。 FORTRAN语言的出现,就像天使为人间送来了福音。与经验主义者相同,它允许程序员只关心数学公式的计算,而无须考虑其他的内容。程序员可以完全不用了解汇编语言,也不用再关心计算机内部的技术细节。他们完全可以把这些琐碎的事情丢到一边,更专注于更重要的事情,如如何将数学公式写成相应的算法步骤交给计算机进行运算。FORTRA... 查看全部[ 1.2 软件的演变过程 ]
1.3 大型软件
在21世纪的前10年中,大部分软件系统都可以用脏乱差来形容,没有哪个软件的设计配得上用优雅这个词。这主要是因为开发时,大家的目标就是用尽可能少的资源来尽快地开发完项目。为了达到这个目标,开发团队往往直接复用现有的一些软件框架,而完全不顾这些重量级的框架其实是远远超出他们的需要。 发布网页 最近,我想在自己的服务器上放一个动态网页。有两种方法来完成这件事,一是在某个端口开一个套接字,读入数据流,再写点什么作为应答;二是基于现有的一些技术组装个系统。这两种方法我都尝试了一下。 首先尝试的是第一种方法,即“从零开始”。我先阅读HTTP协议规范的相关文档,解析读入的头文件,再写了输出。完成这些功... 查看全部[ 1.3 大型软件 ]
1.4 漂亮,真理①和优雅
我敢肯定本书的很多读者对于我美化无绪会愤愤不平。现在这样一种重量级的开发方式往往会把一个程序变成一堆垃圾,怎么能用这种开发方式取代以前那种优雅的软件开发呢?如此丑陋的应用怎么能够保证其正确性呢?其实答案是肯定的,我们只需要去仔细看一下我们大部分人现在所担心的事情。 科学理念仍然深植在我们心中,并始终影响着我们的思维方式。这些由多个世纪以前的古希腊人创建的科学,仍然能在今天影响着我们如何看待真理和美丽之间的关系。对古希腊哲学家来说,最有价值的科学知识其定义是非常简明的,这些知识不会被他人误解,其意义清楚明白,绝不含糊,于是几何学就成为所有科学中最有价值的。这是因为几何学不是一个关于现实世界的科... 查看全部[ 1.4 漂亮,真理①和优雅 ]
1.5 更好的无绪
我们已经看到,简单和优雅都不会作为评价软件部署成功的标准。就像哲学,理性主义过于学术化了,不能帮助我们去理解现实世界中的日常问题。而那种推土机式的务实工作方式,却让人感觉很有发展前途:把市场上可用的组件装配成应用程序,不管用了多少功能库,都把它们粘在一起,只要它能用,也不需要了解清楚个所以然出来。虽然很多人不认同这个观点,但它的确是当今大型软件项目不由自主采用的做事风格。然而,既然现在已经认识到了这个问题,我们能否使无绪的方法更好地工作呢? 推土机式的工作方法的优点在于,即使参与者(如程序员)不完全了解系统情况,也能得到不错的结果。第一次听到这种话你可能会吓一跳。但事实上,我们一直都是这么干... 查看全部[ 1.5 更好的无绪 ]
***
设计API并不容易,且代价不菲。相比之下,试图创建一个带有API的产品比发布一个丝毫不包含任何API的产品工作量要大得多,而且后者更加容易。尽管如此,在“无绪”的原则下,我们认为,基于设计合理的API,你可以设计出更好的软件系统,同时无需深入地了解系统细节。在开发系统子模块时,良好的设计,加之使用系统各个独立组件的API可以有效地改善你设计时所使用的系统工程方法论。改进现有的系统设计技能,是一种将“无绪”利益最大化的有效途径。... 查看全部[ *** ]
2.1 分布式开发
无绪的模型需要利用全世界范围的软件项目中大的组件模块,以装配的方式来开发应用程序。要尽可能多地复用,而不要从零开始编写软件,这样就可以保证产品团队能将重点集中在软件的独特功能上,即应用程序的具体业务逻辑上。这样,开发人员就无需花费时间去创建和编写基础设施,重用现有的框架和由第三方提供的功能库即可。相信现在不会有人因为自用的原因去写一个SQL数据库服务器软件,而是会使用一些商业或者开源的数据库。创建一个私用的数据库可以说是一种低效的资源浪费。对于软件技术的其他领域也是如此。Web服务器、编程语言及其功能库、集成开发环境还有富客户端程序框架①都已经有设计良好的组件可供使用了。就像活动板房,只需将其... 查看全部[ 2.1 分布式开发 ]
2.2 模块化应用程序
模块化的应用程序是由分布式团队开发出来的独立组件组成的。这些独立的组件通常都会提供一个自己的API,当然在具体执行的时候,也需要第三方组件的API或者其他功能才能保证正确运行。例如,Tomcat服务器需要Java运行时实现。同样,标准的C++模板库也需要libc,这样才能调用printf方法。如果使用了大量的组件,那么面临的最大问题就是能否看清整个应用的全貌。只有理解了整个系统以后,才能理清楚模块间的交互关系。在上一节中,我们可以看到一个组件的API只会把其最重要的功能给暴露出来,大部分情况下,用户无需关注其内部的实现,只需要集中精力了解API即可。但如果系统包含成千上万个组件的话,光是组件A... 查看全部[ 2.2 模块化应用程序 ]
2.3 交流互通才是一切
到这里,我们理想的应用程序的轮廓应该很清楚了。应用程序应该基于无绪原则来开发,尽量让最终负责集成的相关人员不需要深入了解系统也可以把集成工作做好。所以,我们理想的应用程序应该基于模块化架构来开发,可以由散布在世界各地的独立开发团队分别负责编写相应的模块。他们可以按照自己的日程来安排工作,以达到最终的目标。但这种做法却存在一个重要的问题,那就是模块间的关联关系。 大多数模块并不能孤立存在,它们要依赖于其他模块提供的环境。只有少数模块才可能完全不依赖其他模块而独立对外提供功能。实际上,大部分模块化的组件都需要其他组件为其提供服务。这就意味着这些模块的开发人员需要去发现和了解如何使用外部模块提供的... 查看全部[ 2.3 交流互通才是一切 ]
2.4 经验主义编程方式
很少有人能够以合理的方式来分析一个新API。没有人在学习使用一个API的时候,去尽力理解该API背后的设计思路。现实正是如此:现在的开发人员想的是在无需理解所有内容的情况下,尽快完成他们的工作,如果他们使用的API能够完成他们的工作,就不会花时间来深入思考这个API。 在本书第1章中提到的那些经验主义哲学家,如果看到了这种情况,想必会非常自豪。不需要花费大量时间来思考、学习和理解相应的内容,开发人员就可以通过尝试调用API中的某个方法来测试是否可以完成其目的。如果测试结果正确,开发人员就会很开心。如果测试结果不正确,开发人员就会继续调用别的方法。NetBeans开发人员把这种开发方式称为经验... 查看全部[ 2.4 经验主义编程方式 ]
2.5 开发第一个版本通常比较容易
如果你想说服其他程序员使用你设计的API,那么必须先取得他们的信任。你需要让这些程序员们相信,你有能力来设计、编写和维护一个稳定的API,而且能在后续的多个版本中坚持做到这一点。即使不考虑使用一个API有多困难,如果该API的新版本发布后,所有的客户端代码都需要重写,这简直就是厄运的开始。想一下,有这么多的开发商①在微软的Windows平台开发程序,如果因为Windows用户安装了一个操作系统的新版本,所有的程序都无法正常运行了,估计真是一场大的厄运。因此API设计会涉及一个信任问题:通过遵守本书给出的最佳实践,可以有效地减少不兼容问题,从而获得用户的信任。 有时对兼容性的破坏是无法避免的,... 查看全部[ 2.5 开发第一个版本通常比较容易 ]
书名: 软件框架设计的艺术
作者: [捷克] Jaroslav Tulach
出版社: 人民邮电出版社
原作名: Practical API Design: Confessions of a Java Framework Architect
译者: 王磊 | 朱兴
出版年: 2011-3
页数: 388
定价: 75.00元
装帧: 平装
丛书: 图灵程序设计丛书
ISBN: 9787115248497