花了一个月的时间看了《代码大全2》的前半部分,期间简单记录了一些个人认为比较重要的点:平常的项目开发的每一个流程都应该认真对待,认真核对checklist:
需求(需求规格说明书),具体checklist
架构与基础数制支持(架构图,数据交互&流通,风险点&复杂度&接口人&工作量)
设计(子模块的设计,类的设计,子程序的设计,注意容易改变的区域&松散耦合&设计模式&信息隐藏&分层设计&模块黑匣子化)
设计实践
- :通过迭代(iterate)自上而下再自下而上的去迭代优化自己的设计图
可以工作的类(涉及软件设计八大原则)
- :一个类只能实现一个ADT,想清楚这个类所实现的抽象是什么?不要混杂抽象层次,即单一职责原则 - :Liskov替换原则就表明了什么时候才是使用继承的场景,除非派生类真的“是一个”更特殊的基类,而且确保只继承需要继承的部分 - :尽量少的类内子程序的数量&调用量
子程序:
- :高内聚:一个子程序内的操作一定是紧密相关的,单一职责 - :子程序参数:输入->修改->输出,不要把参数用作工作变量,参数限制7个以内 - : checklist
防御式编程:不要因为入参数据,让自己的程序崩溃
- :断言使用:错误码处理预期发生的状况,断言处理绝不应该发生的状况 - :错误处理技术:返回中立值,换下一数据,换用接近的合法值,日志异常信息打印,返回错误码,调用错误处理子程序,关闭程序, - :程序健壮性 - :高层次设计对错误进行一致的处理方式 - :不能用异常来推卸责任,能处理的地方一定要处理。 - :抛出的异常抽象层次应该和对应方法(method)处在同一层次 - :异常信息里应该包括所有的相关上下文,了解所用函数库可能抛出的异常,创建统一的异常报告机制(埋点,监控,报警之类) - :迟早引入辅助调试的代码,采用进攻式编程
伪代码编程过程:目的就是在创建类与子程序之前,好好想想,细节多想想,命名多想想,好好设计,信息隐藏,抽象同一层次,单一原则
使用变量的一般注意事项
- :尽量使用final,尽量把变量的作用域变得最小,尽量缩短变量的存活时间 - :变量声明与赋值(初始化)的位置离使用此变量的代码块最近,也是为了缩小作用域 - :绑定时间(把变量和它的值绑定在一起的时间)越晚越好 - :每个变量只用于单一用途,避免让变量具有隐含含义,
基本数据类型
- :避免魔法数
组织直线型代码
- :使代码易于自上而下地阅读 - :把相关的语句组织在一起
使用条件语句
- :首先写正常代码路径,再处理不还情况,把正常情况放在if后面而不要放在else后面,不要交叉处理正确与错误情况 - :把最常用见的情况写到最前面的if语句中,选择最有效的排列顺序(字母或数字顺序 or 正常情况放前面 or 执行频率排序) - :switch case语句的default子句应该被用户处理错误的情况
循环控制
- :在while循环更适用的时候,不要使用for循环 - :一个循环只做一件事,除非测试数据明确显示这部分有性能问题
不常见的控制结构
- :递归: 1):确认递归能够停止 2):使用安全计数器防止出现无穷递归 3):把递归限制在一个子程序内 4):留心栈空间 5):不要用递归去计算阶乘或斐波那契数列(权衡递归方案与栈和循环方案的优劣(性能和可读性)) - :goto: - : return
表驱动法:拯救复杂的逻辑语句
- :典型的示例“灵活的消息格式” - :case -->表驱动,if-->表驱动,完全去除复杂的case与if语句 - :构造查询键值:使用函数将键值转换成与表的key关联, 其中:max(min(66,age),17)== (if(age<17) return 17 else if(age >66) return 66 else return age) - :索引访问表:数据-->索引表-->主查询表 - :阶梯访问表:适用于等级范围查询表 - :表查询法可以把表数据存储在外部并在运行期间读入,不修改代码即可生效
一般控制问题
- :布尔表达式 1:把复杂表达式做成布尔函数,对每一个单元的逻辑值定义合理命名的临时变量 2:用决策表代替复杂条件(有点表驱动法的意思,tripcar里用过这个方法) 3:编写肯定形式的表达式 4:狄摩根定理:逻辑表达式的转换法则 5:按照数轴的顺序编写数值表达式 - :空语句:为空语句创建一个doNothing()的子程序,而不是只一行空行 - :驯服危险的深层嵌套:嵌套一定不要大于三层 1:使用break块来简化嵌套if 2:把嵌套if转换成case语句 3:把深层嵌套的代码抽取出来放进单独的子程序 4:使用一种面向对象的方法(多态+factory method) 5:复杂的代码表明你还没有充分理解你的程序,所以无法简化它,深层嵌套就是一个警告 - :衡量程序的复杂度