首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

在我的职业生涯中,我看到了PC之星的升起和大型机之星的陨落,我看到图形用户界面程序代替了字符界面程序,我还看到了Web的崛起和Windows的衰落。我只能假设当你读到这本书的时候,又会有某些新的技术蒸蒸日上,而我今天(2004年)所知道的Web编程将会慢慢消失。这些技术周期(或者说是技术浪潮)意味着不同的编程实践,编程实践取决于你在技术浪潮中所处的位置。

在成熟的技术环境下——浪潮的末尾,例如21世纪最初10年的中期的网络编程——我们受益于丰富的软件开发基础设施。在浪潮的后期,我们有大量的编程语言可供选择,拥有能对这些语言的代码进行完善的错误检查的工具、强大的调试工具以及自动的可靠的性能优化工具。编译器几乎没有bug。各种工具都有很好的文档,它们来自工具提供商、第三方书籍文章以及大量的Web资源。各种工具集成在一起,因此可以在单个开发环境里面设计用户界面、数据库、报表、业务逻辑等。如果确实遇到问题了,很容易就可以在常见问题列表(FAQ)中找到对工具的各种古怪行为的描述。此外,还有许多顾问可供咨询,训练课程也随处可见。

在技术浪潮的前期——例如20世纪90年代中期的网络编程——情况正好相反。可选择的编程语言非常少,而那些语言往往有很多bug并且文档也很糟糕。程序员花费了大量时间,仅仅是为了弄清楚语言如何工作,而非编写新的代码。程序员还花费无数的时间来绕过(work around)语言产品的bug、下层操作系统的bug以及其他工具的bug。浪潮早期的编程工具往往很原始。可能根本没有调试器,编译器优化在某些程序员的眼中还仅是一种对未来的期盼。工具供应商经常修订编译器的版本,而每一个新的版本似乎都破坏了你代码中的某些重要部分。工具还没有集成起来,所以你往往需要使用不同的工具完成用户界面、数据库、报表、业务逻辑的设计。不同工具很可能互不兼容,你需要花费大量的精力,与编译器和函数库的新发布版本所带来的冲击抗衡,而这么做仅仅为了保持代码现有的功能。如果你遇到了麻烦,在网上可以找到某种形式的参考文献,但它不总是可靠的;而且如果可用的文献是一本指南,那么每次你遇到麻烦的时候,你总觉得像是第一个遇到这种问题的人。

这些评论看起来似乎在建议:应该避免在浪潮的早期搞编程,但这并不是我的意思。一些最具创造力的应用程序就是从浪潮早期的程序中涌现出来的,例如Turbo PascalLotus 123Microsoft WordMosaic浏览器。关键在于,“你如何面对自己的编程工作”,取决于你在技术浪潮中所处的位置。如果处在浪潮的后期,你就可以计划用大部分时间稳定持续地编写新功能。如果你处在浪潮的前期,可以预期你将要花很大一部分时间,用来找出文档中未加说明的编程语言特性、调试程序库代码缺陷带来的错误、修订代码以适应厂商提供的新版本函数库等。

如果你正在一个很初级(简陋)的环境下工作,你会发现,与成熟的环境相比,本书介绍的编程实践将更有帮助。正如David Gries所言,编程工具不应该决定你的编程思路(1981)。Gries对“在一种语言上编程(programming in a language)”和“深入一种语言去编程(programming into a language)”做了区分。“在一种语言上编程”的程序员将他们的思想限制于“语言直接支持的那些构件”。如果语言工具是初级的,那么程序员的思想也是初级的。

“深入一种语言去编程”的程序员首先决定他要表达的思想是什么,然后决定如何使用特定语言提供的工具来表达这些思想。

Example of Programming into a Language

深入一种语言去编程的例子

Visual Basic的早期,我想把产品中的业务逻辑、用户界面、数据库分离开,但没能做到,因为语言中没有任何内置的方法能做到这一点。我知道如果不小心处理的话,过一段时间某些Visual Basic“窗体/form”就会包含业务逻辑,某些会包含数据库代码,而一些窗体可能两者都不包含——最后我可能再也记不清楚哪段代码放在哪个地方了。当时我刚刚完成了一个C++项目,该项目里没能很好地分离这些功能,我不想再用另一种语言尝试一遍这种令人头痛的事情。

因此,我采用了一种设计约定,即只允许 .frm文件(窗体文件)从数据库读取数据或者将数据存入数据库。不允许数据直接通向程序的其他部分。每个窗体都有一个IsFormCompleted()子程序,其他子程序调用它来判断当前激活的那个窗体是否已经保存了自己的数据。IsFormCompleted()是窗体允许拥有的唯一的公用public子程序。同时不允许窗体包含任何业务逻辑。所有其他代码必须放在对应的 .bas文件中,包括检查窗体中数据的有效性的代码。

Visual Basic并不鼓励这种方法,它鼓励程序员把尽可能多的代码放在.frm文件中,并且,“在 .frm文件中回调对应的 .bas文件中的子程序”也不容易。

这一约定虽然非常简单,但是随着项目的深入,我发现它给了我很大帮助;假如没有这一约定,我将写出很多纠缠而费解的代码。假如没有这一约定,我也许就会加载某个窗体之后不显示它,只为调用其中检查数据有效性的子程序;或者我也许会将窗体中的代码复制到其他地方,然后维护这些分布在各处的功能相同的代码。IsFormCompleted()约定同样使得事情变得简单。因为每个窗体都以完全相同的方式工作,我不需要预测IsFormCompleted()的语义——每次用到它都代表相同的意思。

Visual Basic并不直接支持这种约定,但是我使用了这一简单的编程约定——深入一种语言去编程——补偿了语言当时的结构缺陷,并且使得该项目易于管理。

理解“在一种语言上编程”和“深入一种语言去编程”的区别,对于理解本书是至关重要的。大多数重要的编程原则并不依赖特定的语言,而依赖于你使用语言的方式。如果你使用的语言缺乏你希望用的构件,或者倾向于出现其他种类的问题,那就应该试着去弥补它。发明你自己的编码约定、标准、类库以及其他改进措施。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论