代码大全2(读书笔记10)

109、为未来的变化做准备

  如果你预计到某个程序会被修改,你可以把预计要被改动的部分放到单独的类里,同其他部分隔离开,这是个好主意。之后你就可以只修改这个类或用新的类来取代它,而不会影响到程序的其余部分了。

 

110、子程序优点一-----------降低复杂度

  创建子程序的一个最重要的原因,就是为了降低程序的复杂度。可能通过创建子程序来隐藏一些信息,这样你就不必再考虑这些信息了。当然,在你要编写这个子程序的时候肯定是要考虑它们的。不过一旦程序写好了,你就应该能忘记这些细节。(自己思考的单位越大,办的事就越大,包含的范围也越多)可以直接调用该子程序而无须了解其内部工作细节。创建子程序还有其他一些原因---------缩小代码规模、改善可维护性、提高正确性等--------也都是很不错的,但如果没有子程序的抽象能力,我们的智力将根本无法管理复杂的程序。

  当内部循环或条件判断的嵌套层次很深时,就意味着需要从了程序中提取出新的子程序了。把嵌套的部分提取出来形成一个独立的子程序,可以降低外围子程序的复杂度。

 

111、子程序优点二-----------引入中间、易懂的抽象

  把一段代码放入一个命名恰当的子程序内,是说明这段代码用意最好的方法之一。与读下面这五中语句相比,

if (node <> NULL)  then

   while(node.next <>NULL) do

     node=node.next

     leafName=node.name

   end while

else

  leafName=""

end if

读懂下面这条语句就更容易

leafName=GetLeafName(node)

  这段新程序如此之短,只要给它取个好的名字就足够说明它的用意了。与上面8行代码相比,这个名字提供了更高层次的抽象,从而使代码更具可读性,也更容易理解,同时也降低了原来包含着上面那段代码的子程序的复杂度。

 

111、子程序优点三-----------减少改动量、保证代码质量

  只要改动子程序,就可对所有调用子程序的地方生效。而且,如果每处都要改,难免出现漏掉的或改错的。

 

 

112、内聚性

  一项针对450个子程序所做的研究发现,高内聚性的子程序中有50%没有任何错误,而低内聚性的子程序中只有18%是没有错误的(Card,Carch and Agresti 1986)。另一项针对另外450个子程序(选取了同样数量的子程序进行研究纯属巧合)所做的研究发现,耦合度与内聚性之比最高的那些子程序,其中所含的错误是耦合度与内聚性之比最低的子程序的7倍之多,而其修正成本则为20倍(Selby and Basili 1991)。

 

113、最好的内聚性

  是最强也是最好的一种内聚性,也就是说让一个子程序仅执行一项操作。例如sin(),GetCustomerName()EraseFile()CalculateLoanPayment()以及AgeFromBirthdate()这样的子程序都是高度内聚的。当然,以这种方式来评估内聚性,前提是子程序所执行的操作与其名字相符--------如果它还做了其他的操作,那么它就不够内聚,同时其命名也有问题。

 

114、参数顺序

   如果几个程序都用了类似的一些参数,应该让这些参数的排列顺序保持一致 子程序的参数顺序可以产生记忆效应――不一致的顺序会让参数难以记忆 。比如说在C语言中,fprintf()函数比printf()函数就是多了一个放在开头的文件参数而已,其他都完全一样。而与这类似的函数fputs(),它比puts只多了一个放在最后的文件参数。本来应该很容易记住的参数,却因为这点儿毫无道理的可气的区别而变得难以记忆了。

   而另一方面,C语言中的strncpy()函数所接受的参数依次是目标字符串、源字符串和最大字节数,memcpy()函数也是接受同样顺序相同的参数。这两个函数的相似性对记住函数中的参数不无裨益。

 

115、函数与过程的区别

  函数是指有返回值的子程序;过程是指没有返回值的子程序。

 

116、健壮性与正确性

  正如前面视频游戏和X光机的例子告诉我们的,处理错误最恰当的方式要根据出现错误的软件的类别而定。这两个例子还表明,错误处理方式有时更侧重于正确性,而有时则更侧重于健壮性。开发人员倾向于非形式地使用这两个术语,但严格来说,这两个术语在程度上截然相反的。正确性意味着永不返回不准确的结果,哪怕不返回结果也比返回不准确的结果好。然而,健壮性则意味着要不断尝试采取某些措施,以保证软件可以持续地运转下去,哪怕有时做出一些不够准确的结果。

  人身安全攸关的软件往往更倾向于正确性而健壮性。不返回结果也比返回错误的结果要好。放射线治疗仪就是体现这一原则的好例子。

   消费类应用软件往往更注重健壮性而非正确性。通常只要返回一些结果就比软件停止运行要强。我所用的字处理软件有时会在屏幕下方显示半行文字。如果它检测到这一情况,难道我期望字处理软件退出吗?当然不。我知道等下次再按Page Up或Page Down键之后屏幕就会刷新,随后显示状态也就恢复正常了。

 

117、隔离程序,使之包容由错误造成的损害

  隔栏是一种容损策略。这与船体外壳上装备隔离舱的原因是类似的。如果船只与冰山相撞船体破裂的话,隔离舱就被封闭起来,从而保证船体的其余部位不会受到影响。这也与建筑物里的防火墙很相像。在发生火灾时,建筑物里的防火墙能阻止火势从建筑物的一个部位向其他部位蔓延。

 

118、数据净化装置

  让软件的某些部分处理“不干净的”数据,而让另一些部分处理“干净的”数据,即可让大部分代码无须再担负检查错误数据的职责

  也同样可以在类的层次采用这种方法。类的公用方法可以假设数据是不安全的,它们要负责检查数据并进行清理。一旦类的公用方法接受了数据,那么类的私用方法就可以假定数据都是安全的了。

  也可以把这种方法看做是手术室里使用的一种技术。任何东西在允许进入手术室之前都要经过消毒处理。因此手术室内的任何东西都可以认为是安全的。这其中最核心的设计决策是规定什么可以进入手术室,什么不可以进入,还有把手术室的门设在哪里―――在编程中也就是规定,哪些子程序可认为是在安全区域里的,哪些又是在安全区域外的,哪些负责清理数据。完成这一工作最简单的方法是在得到外部数据时立即进行清理,不过数据往往需要经过一层以上的清理,因此多层清理有时也是必需的。

 

119、伪代码

伪代码其实就是一个建模。是人的思想与实际代码的一个中间过程。一坐桥梁。

伪代码是一种与使用何种语言无关的方法。

  由于伪代码看起来很像英语,你可能会很自然地认为,任何可以用来收集想法的类似英语的描述,能起的作用都是大同小异的。而实践中你则会发现,某些形式的伪代码要比其他形式的更有用。下面是一些有效使用伪代码的指导原则。

(1)用类似英语的语句来精确描述特定的操作。

(2)避免使用目标编程语言中的语法元素。伪代码能让你在一个比代码本身略高的层次上进行设计 。当用编程语言来构建时,你就又降到了更低的层次上,这不但失去了在更高层次上设计时所能得到的主要好处,而且也会受限于不必要的语法上的约束。

(3)本意的层面上编写的伪代码。用伪代码去描述解决问题的方法的意图,而不是去写如何在目标语言中实现这个方法。

(4)在一个足够低的层次上编写伪代码,以便可以近乎自动地从它生成代码。如果伪代码的层次太高,就会掩盖代码中的问题细节。你应该不断地精华伪代码,加入越来越多的细节,直到看起来已经很容易直接写出代码为止。

伪代码一经写好,你就可以依照它去生成代码了,同时还把伪代码变成编程语言中的注释。这样就节省了大部分注释工作。

 

120、自己程序的BUG还是系统错误

  编程爱好者和专业程序员之间最大的区别之一便是从迷信到理解的转变。这里所说的“迷信”并不是指一个程序会在月圆之时让你心生惊恐或产生什么莫名其妙的错误。指的是把对代码的感觉当作对它的理解。如果你发现自己经常怀疑某些错误是由编译器或硬件造成的,那么你就仍然处于迷信的阶段。多年以前的一份研究表明,只有约5%的错误是由硬件、编译器或操作系统的原因造成的。今天这一比例甚至可能更低。已经从迷信转为理解的程序员们总会先怀疑是自己的工作出了问题,因为他们知道,正是他们制造了那95%的错误。理解每一行代码所起的作用,理解为什么需要这行代码。没有什么东西会仅仅因为它看上去可行就是正确的。如果你不知道它为什么可以工作,那么它很可能就是不能工作的------只是你还不知道罢了。

  这里的底线是:只是能写出一个可以工作的子程序是不够的。如果你不知道它为什么可以工作,那就去研究它,讨论它,用其他的设计作试验,直到你弄明白为止。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值