欣赏优美的代码:实际的例子

2008-04-09 04:03:04来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

  上一节我们讨论了优美的子程序对整体系统的影响,但是大家可能还是比较模糊,让我们来看一个实际的例子:

  在讨论高质量子程序的细节问题之前,我们首先来考虑两个基本名词。什么叫“子程序”?子程序是具有单一功能的可调用的函数或过程。比如C 中的函数,Pascal 或Ada 中的函数或过程,Basic中的子程序或Fortran 中的子程序。有时,C 中的宏指令或者Basic中用GOSUB调用的代码块也可认为是子程序。在生成上述函数或过程中,都可以使用创建高质量子程序所使用的技术。什么是“高质量的子程序”?这是一个比较难以回答的问题。反过来最简单回答方式是指出高质量子程序不是什么。下面是一个典型的劣质子程序(用Pascal写成):

Procedure HandleStuff ( Var InputRec:CORP_DATA,CrntQtr:integer,
EmpRec:Emp_DATA, Var EstimRevenue:Real, YTDRevenue:Real,
ScreenX:integer,ScreenY:integer,Var NewColor:Color_TYPE,
Var PrevColor:COLOR_TYPE,Var Status:STATUS_TYPE,
ExpenseType:integer);
 begin
  for i := 1 to 100 do begin
   InputRec.revenue[1]:= 0;
   InputRec.expense[i]:=CorpExpensse[CrntQtr,i]
  end;
  UpdateCorpDatabase(EmpRec);
  EstimRevenue:=YTDRevenue * 4.0 /real(CrntQtr)
  NewColor:=PrevColor;
  status:=Success;
  if ExpenseType=1 then begin
   for i:= 1 to 12 do
    Profit[i]:= Revenue[i]-Expense.Type[i]
   end
  else If ExpneseType= 2 then begin
   Peofit[i]:=Revenue[i] - Expense.Type2[i]
  end
  else if ExpenseType= 3 then
  begin
   Profit[i]:=Revenue[i] - Expense.Type3[i]
  end
end
  这个子程序有什么问题?给你一个提示:你应该至少从中发现10个问题。当你列出所发现的问题后,再看一下下面所列出的问题:

  · 程序的名字让人困惑。Handlestuff()能告诉我们程序是干什么的吗?

  · 程序没有被说明。

  · 子程序的布局不好。代码的物理组织形式几乎没有给出其逻辑组织形式的任何信息。布局的使用过于随心所欲,程序每一部分的布局都是不一样的。关于这一点。只要比较一下ExpenseType=2 和ExpenseType=3 两个地方的风格就清楚了。

  · 子程序的输入变量值InPutRec 被改变过。如果它作为输入变量,那它的值就不该变化。如果要变化它的值,就不该称之为输入变量InputRec。

  · 子程序进行了全局变量的读写操作。它从CorpExpense 中读入变量并写给Profit。它应该与存取子程序通信,而不应直接读写全局变量。

  · 这个子程序的功用不是单一的。它初始化了某些变量。对一个数据库进行写操作,又进行了某些计算工作,而它们又看不出任何联系。一个子程序的功用应该是单一,明了的。

  · 子程序中没有采取预防非法数据的措施。如果CrntQtr 的值为“0”,那么,表达式YTDRevenue*4.0/real(CrntQtr)就会出现被零除的错误。

  · 程序中使用了几个常数:100, 4.0, 12, 2和3。

  · 在程序中仅使用了域的CORP_DATA 型参数的两个域。如果仅仅使用两个域,那就该仅仅传入特定的域而不是整个结构化变量。

  · 子程序中的一些参数没有使用过。ScreenX 和ScreenY 在程序中没有涉及。

  · 程序中的一个参数被错误标定了。PrevColor被标定为变量型参数,然而在程序中又没有对其赋值。

  · 程序中的参数太多。程序中参数个数的合理上限应该是七个左右。而这个程序中则多达11个。程序中的参数多得怕人,恐怕没谁会仔细检查它们,而且连数一下都不愿意。

  这么一小段代码竟然有这么多的错误,这些错误你是不是能够都避免呢?如果是,那么恭喜你,你的程序员的功底相当深。虽然说这些错误并不是很大不了的东西,丝毫不影响程序的正确性和速度。在系统越来越复杂的现代,如果系统里的每一个子程序的复杂度、可读性、耦合度都影响到整体系统的成功与否。但是如果是在写个人的程序,那你是对自己的虐待,如果是做为开发团体的一分子,那么,你的做法是对同伴的虐待。

  除了计算机本身之外,子程序可以说是计算机科学最重大的发明。子程序使得非常好读而且也非常容易理解,编程语言中的任何特性都不能和这一点相比。像上例中那样使用子程序,简直就是对子程序的践踏,甚至可以说是一种犯罪。

  子程序也是节省空间和提高性能的最好手段。想象一下,如果用代码段去代替程序中对子程序的每一次调用,那么程序将会有多么庞大。如果不是把多次重复使用的代码段存放在子程序中,而是直接把它放在程序中,那么对其进行性能改进将是一件很困难的事。是子程序使现代编程成为可能。

  现在,你可能有些不耐烦。“是好,子程序的确很了不起,我一直都在使用它”。你说,“你的讨论似乎像是在纠正什么,你到底想让我做什么呢?”

  我想说的是:有许多合理的原因使得我们去生成子程序。但是生成方法有好有坏。作为一个计算机专业的本科生,可以认为生成子程序的主要原因是避免代码段的重复。我所用的入门课本告诉我说,之所以使用于程序,是因为它可以避免代码段的重复,从而使得一个程序的开发、调试、注释和维护工作都变得非常容易。除了一些关于如何使用参数和局部变量的语法细节之外,这就是那本课本关于子程序理论与实践内容的全部。这实在不是一个完全而合理的解释。

  子程序的好处我们在上一节有详细的阐述,既然子程序有着这么多的好处,那么编写一个优美甚至完美的子程序对我们有什么困难的呢,其实这是一个思想和习惯的问题。程序员就一定是那种穿裤衩儿背心,听着摇滚写程序的人吗?我觉得真正的程序员应该是一丝不苟的,分析需求、确定架构、做概要设计和详细设计、单元测试、整理所有文档。麻烦吧,是很麻烦,但是这会为你带来意想不到的惊喜。你会发现你的程序是那么的清晰:再多的版本也不会把你的脑袋搞晕,一个小错误在数万行的代码中轻易的被定位del,用户提出新的需求是你的脸色不再难看…。所有的这些只意味着一件事:你成功的控制住了出自你手的程序。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:优美程序还需优美子程序

下一篇:游戏开发新手入门之调色板和像素