目录
4.3.2 “在一种语言上编程”和“深入一种语言去编程”的区别
第3章“三思而后行:前期准备”讨论了设计蓝图和建筑许可证在软件业里的等价物。你可能对那些准备工作没有多少发言权,所以第3章关注的焦点是确定“当构建开始后你需要做什么”。
本章关注的焦点是程序员和技术带头人个人必须(直接或间接)负责的准备工作。
程序员使用熟悉的语言时,生产率比使用不熟悉的语言时要高。
编程语言影响程序员的思维的证据随处可见。典型的故事类似下面的样子:“我们用 C++编写一个新系统,但是大多数程序员没有太多 C++经验。他们具有Fortran 语言背景。他们编写出能用 C++编译的代码,但实际上编写的是伪装成 C++的 Fortran 代码。他们扭曲 C++来模拟 Fortran 的不良特性(例如 goto 语句和全局数据)并且忽略了 C++丰富的面向对象能力。”这种现象多年来在整个行业当中随处可见(Hanson 1984, Yourdon 1986a)。
交叉引用:关于“约定的威力”的更多细节,见第11.3节至11.5节。
在高质量软件中,你可以看到“架构的概念完整性”与“其底层实现”之间的关系。“实现”必须与(指导该实现的)“架构〞保持一致,并且这种一致性是内在的、固有的。 在“构建”开始之前,讲清楚你使用的编程约定。这正是变量名称、类的名称,子程序名称、格式约定、注释约定等这些针对“构建活动”的指导方针的关键所在。
任何大型的程序都需要一个控制结构,该结构可以统一编程语言的细节。大型结构的部分魅力在于,各个具体部件都能反映整体架构的内涵。假如没有一种统一的规则,你创作出来的东西将会充斥着各种不同的风格,显得混乱而邋遢。这些不同的风格将使你的大脑承受沉重负担—而这仅仅是为了理解不同编程风格之间的(本质上是随意的)差异。成功编程的一个关键就在于避免随意地变化,这样你的大脑可以专注于那些真正需要的变化。关于这方面的更多信息,见第5.2节“软件的首要技术使命:管理复杂度”。
你需要知道,你目前使用的技术现在处于哪种阶段?这个技术是”浪潮的末尾“还是”浪潮的初期“。
关键在于,“你如何面对自己的编程工作”,取决于你在技术浪潮中所处的位置:
在 Visual Basic 的早期,我想把产品中的业务逻辑、用户界面、数据库分离开,但没能做到,因为语言中没有任何内置的方法能做到这一点。我知道如果不小心处理的话,过一段时间某些 Visual Basic “ 窗体/form” 就会包含业务逻辑,某些会包含数据库代码,而一些窗体可能两者都不包含——最后我可能再也记不清楚哪段代码放在哪个地方了。当时我刚刚完成了一个 C++项目,该项目里没能很好地分离这些功能,我不想再用另一种语言尝试一遍这种令人头痛的事情。
因此,我采用了一种设计约定,即只允许.frm 文件(窗体文件)从数据库读取数据或者将数据存入数据库。不允许数据直接通向程序的其他部分。每个窗体都有一个 IsFormcompleted()子程序,其他子程序调用它来判断当前激活的那个窗体是否已经保存了自己的数据。IsFormCompleted()是窗体允许拥有的唯一的公用(public)子程序。同时不允许窗体包含任何业务逻辑。所有其他代码必须放在对应的.bas 文件中,包括检查窗体中数据的有效性的代码。
Visual Basic 并不鼓励这种方法,它鼓励程序员把尽可能多的代码放在.frm文件中,并且,“在.frm 文件中回调对应的.bas 文件中的子程序〞也不容易。
这一约定虽然非常简单,但是随着项目的深入,我发现它给了我很大帮助。假如没有这一约定,我将写出很多纠缠而费解的代码。假如没有这一约定,我也许就会加载某个窗体之后不显示它,只为调用其中检查数据有效性的子程序;或者我也许会将窗体中的代码复制到其他地方,然后维护这些分布在各处的功能相同的代码。IsFormcompleted()约定同样使得事情变得简单。因为每个窗体都以完全相同的方式工作,我不需要预测 IsFormcompletea() 的语义——每次用到它都代表相同的意思。
Visual Basic 并不直接支持这种约定,但是我使用了这一简单的编程约定——深入一种语言去编程——补偿了语言当时的结构缺陷,并且使得该项目易于管理。
理解“在一种语言上编程”和“深入一种语言去编程”的区别,对于理解本书是至关重要的。大多数重要的编程原则并不依赖特定的语言,而依赖于你使用语言的方式。如果你使用的语言缺乏你希望用的构件,或者倾向于出现其他种类的问题,那就应该试着去弥补它。发明你自己的编码约定、标准、类库以及其他改进措施。
下面的核对表总结了在“构建〞过程中,应该有意识地使用或者排斥的特定编程实践。这些实践的细节遍布全书。
交叉引用:关于质量保证的更多细节,请见第 20章“软件质量概述”。:
关于工具的更多细节:详见第 30章“编程工具”。