代码大全笔记

最近在看代码大全。感觉有些是空谈般的说教,不过大部分内容还是很有借鉴意义的。摘录一些觉得比较有用的内容,当作是学习笔记吧,还不完全,慢慢添加。

6抽象数据类型

6.1 ADT

a. 把底层数据类型抽象为ADT,尽量避免在程序中大量出现底层数据类型的操作。

例如:currentFont.attribute &= 0X42//(Bold)  -> currentFont.setBoldOn()

或者,将用listqueue表示的东西抽象成实际高层次的概念,比如员工,演员列表,提供封装好的接口,而不是底层类型的直接操作。

 

好处:只需修改一处,减少出错可能。代码更容易理解

 

 b. 不要让ADT依赖于特定的介质

例如:一份费率数据,可能存储与磁盘文件中,但以后也许会存储在内存中。所以读取操作应该是rateData.read()而不是rateFile.read()

 

好处: 增加扩展性

 

6.2 接口

a. 类中的接口应该位于同一层次。如果无法做到,需要考虑重新划分类的层次。

 

好处:使得程序易于维护和理解

 

b. 接口同时拥有可编程部分和语义部分。可编程部分由编译器理解,包括参数,返回值等约束,语义部分表示在何种情形下(例如调用顺序, 某变量不能为空)应该,可以调用此接口。由于语义部分无法用编译器约束,需要通过assert等技术来实现。

 

好处:避免接口的错误调用

 

c. 尽可能限制成员的可访问性

 

好处:保持封装性

 

d. 不应该针对类的实现来编写调用代码,而应该根据接口编程。

例如,在执行数据库查询前不调用connect,因为知道查询函数在没有connect时会自动调用connect。这显然破坏了封装性

 

6.3 设计和实现的问题

a. 频繁的case出现可能是在暗示使用继承,实现多态是更好的选择。

 

b. 将构造函数定义为私有,以强制实现singlton.

 

6.4 创建类的原因

 

 

7.高质量的子程序

7.2

a. 应该避免的子程序内聚性如下

过程内聚性:            不太理解

逻辑内聚性:            通过传入的控制标致来决定执行哪种操作,而各种可能的操作间没有逻辑联系。

巧合的内聚性:        各种操作之间没有逻辑联系,通常可视为没有内聚性。没有什么好的解决方案,通常需要深入地重新设计。

 

7.3

a. 子程序命名,尽量描述所有事情,如果不可能,需要考虑重新设计你的子程序。

避免使用dealwithXXX,  processXXX之类的名称, 避免XXX1XXX2这样的命名。

 

7.5

a. 参数排列顺序:输入,修改,输出

b. 引入临时变量并没有什么不好,不要过分地利用参数来存储子程序的中间结果

c. 如果对参数有假定,应该使用断言。

d.什么时候应该传递对象,什么时候传递对象的若干属性呢?一般来说,倘若发现

在传递对象前都是创建对象,然后把需要的属性填充,然后再在子程序里去的这些

属性的话,应该考虑只传递属性。倘若发现自己要频繁的修改子程序的参数表,而

每次修改的参数都源于同一对象,应该考虑传递对象。

 

 

8防御式编程

8.2

a.断言用于检测正常情况下决不应该出项的情况。类似于用户输入这类的数据是可能出错的,所以应该使用错误处理技术而不是断言。

 

8.4

a.抛出异常的层次结构应该与接口的抽象层次一致。比如:

class Employee{

TaxId getTaxId()throws EOFException显然要比

TaxId getTaxId()throws TaxFileUnavailable暴露了更多的实现细节,使得函数的调用方和更低层次的实现耦合而不是和Employee耦合。这样的代码也更难于理解和管理。

b.了解使用的函数库会抛出那些异常,否则程序会莫名的崩溃。这在c++, vb 这种不声明函数抛出异常的语言中很重要。

c.考虑创建一种集中统一的异常报告机制。例如在catch块中的report异常的函数(可能仅仅是在log中打印一些信息,或者做得更多)。

8.5

a.在接受到输入数据(一般为字符串)后应该立刻转化为合适的类型。长时间保持类型不明的数据会增加程序的复杂度和崩溃的可能。

b. 添加数据验证类或者类中加入数据验证函数,就像防火墙一样能保证关键区域不受非法数据的影响。

c.防火墙外部的程序使用错误处理技术,内部使用断言。

 

8.6

a. c,c++中支持通过define, ifndef 等来进行条件编译,而其他语言并不支持。如果有需要,可以自己实现一个预处理器,自定义条件编译的规则,然后编译处理器处理过后的代码

 

9.伪代码编程过程241

 

使用访问其子程序来读写全局变量, 而不是直接存取。将全局变量和相应的访问其分不到合适的类里,而不是将所有全局变量组织在一起(违反速度护具抽象的原则)。

 

不要利用循环计数的值去判断循环是否提前终止,而应该使用状态变量标识(因为潜在的off by one错误增加了前者的出错几率,而且代码不易阅读)。

 

浮点数的比较。永远别指望使用= 判断相等的理由是两者的差值在一个足够小的范围内,例如<0.00001.

 

多重循环时使用有意义的下标。既能避免下标串话,又使代码更可读。

 

不要用递归去解决简单的问题。迭代在任何时候都是更好的选择。

 

goto并不有害,有害的是滥用goto. 在一些产生资源,使用资源,然后释放资源的程序中,goto能减少重复代码,并是代码看上去更清晰。试想我们经常在异常处理,正常结束,或者异常的finally部分重复的调用资源释放代码。如果使用goto…

 

 试着用表驱动来代替过多的if else判断。用数据代替逻辑判断。

 

按照数轴的位置编写数值比较表达式。eg, min < i && i < max.

posted on 2009-07-23 16:16  freestyleking  阅读(315)  评论(0编辑  收藏  举报

导航