代码大全笔记
6抽象数据类型
6.1 ADT
a. 把底层数据类型抽象为ADT,尽量避免在程序中大量出现底层数据类型的操作。
例如:currentFont.attribute &= 0X42//(Bold) -> currentFont.setBoldOn()
或者,将用list或queue表示的东西抽象成实际高层次的概念,比如员工,演员列表,提供封装好的接口,而不是底层类型的直接操作。
好处:只需修改一处,减少出错可能。代码更容易理解
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之类的名称, 避免XXX1,XXX2这样的命名。
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) 编辑 收藏 举报