一旦你能确定 “构建”的基础已经打好,那么准备工作就转变为针对特定“构建”的决策了。第3章“三思而后行:前期准备”讨论了设计蓝图和建筑许可证在软件业务里的等价物。你可能对那些准备工作没有多少发言权,所以在第3章关注的焦点是确定“当构建开始后你需要做什么”。本章关注的焦点是程序员和技术带头人个人必须(直接或间接)负责的准备工作。在向工地进发之前,如何选择适用的工作别在你的腰带上,你的手里车里应该装哪些东西?本章讨论的就是这事务在软件中的等价物。
4.1 选择编程语言(Choice of Programming Language)
研究表明,编程语言的选择从多个方面影响生产效率和代码质量。
程序员适用熟悉的语言时,生产效率比适用不熟悉的语言时要高。适用高级语言的程序员比适用较低级语言的程序员达到更好的生产率和质量。某些语言更能表达编程中的各种概念。
语言描述(Language Descriptions)
介绍了很多种语言,在这里就不写了。
4.2 编程约定(Programming Conventions)
在高质量软件中,你可以看到“架构的概念完整性”与“其底层实现”之间的关系。“实现”必须与(指导该实现的)“架构“保持一致,并且这种一致性是内在的、固有的。这正是变量名称、类的名称、子程序名称、格式约定、注释约定等这些针对”构建活动“的指导方针关键所在。
在一个复杂的程序中,架构上的指导方针使得程序的结构平衡,针对”构建活动“的指导方泽则提供了底层协调,将每个类(Class)都衔接到一种完整的设计(comprehensive design)中,成为其可靠的部件。任何大的程序都需要一个控制结构,该结构可以统一编程语言的细节。大结构的部分魅力在于,各个具体部件都能反映整体架构的内涵。假如没有一个统一的规则,你创作出来得东西将会充斥着各种不同的风格,显得混乱和邋遢。这些不同风格使得你的大脑承受沉重的负担——着仅仅是为了理解不同编程风格之间的(本质是是随意的)差异。成功编程的一个关键就在于避免随意的变化,这样你的大脑可以专注于那些真正需要的变化。
在”构建“开始之前,讲清楚你使用的编程约定。编码约定的细节要达到这样的精确度:在编写完软件之后,几乎不可能改变(翻译)软件所遵循的编码约定。本书随处都有这样的约定细节。
4.3 你在技术浪潮中的位置(Your Location on the Technology Wave)
在我的职业生涯中,我看到了PC之星的升起和大型机之星的陨落,我看到图形用户界面代替了字符界面程序,我还看到了Web的崛起和Windows的衰落。我只能假设当你读到这本书的时候,又会有某些新的技术蒸蒸日上,而我今天(2004年所)知道的Web编程将会慢慢消失。这些技术周期(或者说是技术浪潮)意味着不同的编程实践,编程实践取决于你在技术浪潮中所处的位置。
你如何面对自己的编程工作,取决于你在技术浪潮中所处的位置。如果处在浪潮的后期,你就可以计划用很大部分时间稳定持续的编写新功能。如果你处在浪潮的前期,可以预期你将要花很大一部分时间,用来找出文档中未加说明的编程语言特性、调试程序代码缺陷带来的错误、修订代码以适应厂商提供的新版本函数库等。
如果你在一个很初级(简陋)的环境下工作,你会发现, 与成熟的环境相比,本书介绍的编程实践将更有帮助。正如David Gries所言,编程工具不应该决定你的编程思路(1981)。Gries对”在一种语言上编程(programming in a language)“做了区分。”在一种语言上编程“的程序员将他们的思想限制于”语言直支持的那些构建“。如果语言工具是初级的,那么程序员的思想也是初级的。
”深入一种语言区编程“的程序员首先决定他要表达的思想是什么,然后决定如何使用特定语言提供的工具来表达这些思想。
“深入一种语言去编程”的例子(Example of Programming into a Language)
理解“在一种语言上编程”和“深入一种语言区编程”的区别,对于理解本书是至关中要的。大多数重要的编程原则并不依赖特定的语言,而依赖你使用语言的方式。如果你使用的语言缺乏你希望用的构件,或者倾向于出现其他种类的问题,那就应该试着去弥补它。发明你自己的编码约定、标准、类库以及其他的改进措施。
4.4 选择主要的构件实践方法(Selection of Major Construction Practices)
"构件"有一部分准备工作,就是决定在这么多的可选的实践方法中,你想要强调哪些。某些项目使用结对编程以及测试驱动开发,而其他项目使用单人开发和形式化检查。这两种技术组合都有可能发挥作用,取决于项目的特定环境。
下面的核对表总结了在“构建”过程中,应该有意识地使用或排斥的特定编程实践。这些实践的细节遍布全书。
核对表:主要的构建实践(Checklist:Major Construction Practices)
编码
你有没有确定,多少设计工作将要预先进行,多少设计工作在键盘上进行(在编写代码同时)?
你有没有诸如名称、注释、代码格式等“编码约定”?
你有没有规定特定的由软件架构确定的编码实践,比如如何处理错误条件、如何处理安全性事项、对于类接口有哪些约定、可重用的代码遵循哪些标准、在编码时考虑多少性能因素等?
你有没有找到自己在技术浪潮之中的位置,并相应调整自己的措施?如果必要,你是否知道如何“深入一种语言去编程”,而不受限于语言(仅仅“在一种语言上编程”)?
团队工作
你有没有定义一套集成工序——即,你有没有定义一套特定的步骤,规定程序员在把代码check in(签入)到主源码(代码库)中之前,必须履行这些步骤?
程序员是结对编程、还是独自编程,或者是这二者的某种组合?
质量保证
程序员在编写代码之前,是否为之编写测试用例?
程序员会为自己的代码写单元测试吗?(无论先写还是后写)?
程序员在check in 代码之前,会用调试器单步跟踪整个代码流程吗?
程序员在check in 代码之前,是否进行集成测试(integration-test)?
程序员会复审(review)或检查别人的代码吗?
工具
你是否选用了某种版本控制工具?
你是否选定了一种语言,以及语言的版本或编译器版本?
你是佛选择了某个编程框架,或者明确地决定不使用编程框架?
你是否决定允许使用非标准的语言特性?
你是否选定并拥有了其他将要用到的工具——编译器、重构工具、调试器、测试框架(test framework)、语法检查器等。
要点(Key Points)
每种编程语言都有其优点和弱点。要知道你使用的语言的明确优点和弱点。
在开始编程之前,做好一些约定(convention)。“改变代码使之符合这些约定”是近乎不可能的。
“构建的实践方法”的种类比任何单个项目能用到的要多。有意识的选择最适合你的项目实践方法。
问问你自己,你采用的编程实践是对你所用的编程语言的正确响应,还是受它的控制?请记得“深入一种语言去编程”,不要仅“在一种语言上编程”。
你在技术浪潮中的位置决定了哪种方法是有效的——甚至是可能用到的。确定你在技术浪潮中的位置,并相应调整计划和预期目标。
第四章关键的构建决策(代码大全2)