按照读书顺序整理
述而不作
此版为草稿
第二部分:高质量代码
第六章:可工作的类
a.好处
提高程序自说明性
隐藏细节
隔离复杂度
流畅的参数传递
容易重构
...
public下实质就是对外开放的接口,而private则是封装的细节
ADT:应采用尽可能高的抽象
b.接口设计原则
1.一个类只实现一个ADT,内聚性要高。对类内杂乱的函数:
转移到其他类里,
转移为私用子函数
2.使用一致的抽象层次,混乱的抽象会让程序难以理解:
事务层次的类不应该提供容器的操作窗口,
如果有操作需求,也应是事务概念的操作
3.接口是对捕捉到的抽象进行选择,
4.检查是否存在相反操作需求
5.一半子程序使用一半数据,另一半子 程序使用另外一半数据,那么拆分类吧。
6.尽量把语义接口元素转化为编程接口元素。如使用断言等。
总之,接口应该展示一致的抽象。
c.封装原则
对c++等语言代码中,不要在private部分暴露实现细节。
封装方法是
private EmployImplymentation * m_implymenTation
而把细节放入implymentation类里。
至少读代码时别去私用部分里找细节
封装是对接口编程,而不是对内部实现细节编程。
封装的思维:
如果一个人调用库时发现问题,不应该查阅源代码,而是联系作者去修改发布。类内实现细节不应该影响使用者编程。如:
逻辑过程缺失:perform内包含initial,没读细节的使用者先initial再perform就会出bug
假设过强:使用classA.num代替classB.num.客户不知道他们两个的num相同。
紧密耦合事实上消除了封装性。
e.继承
种类:
公有:class a:public class baseClass;
1.baseClass中public元素在a中还是public,base中private元素在a中不可见
2.代表 is a 关系
私有:class b:public class base
1.base中public元素在b中是private,base中private不可见
何时选择继承:
1.多个类的共有元素需要一个基类去集中
2.派生类必须能够通过基类的接口直接调用
3.LSP原则:使用时无须思考不同派生类的语义含义,即基类提供之接口让人直接理解派生类的行为如:
loanAccount的interest和saveAccount中interest中语义不同,就不应在基类account中放入interest元素,interest的继承并没有减少程序员的思考量
4.不要过度设计。为未来工作着想的方式是让眼下之成果尽可能清晰简单。---只有一个派生类的继承很值得怀疑
5.case语句下多操作都很类似暗示着多态的需求。
而种类确实不同的操作则不必。
6.继承体系尽可能低
几点注意事项:
1.避免万能类,应该把功能放入万能类他所操作的类上去。
2.避免动词命名的类:只有动作而无数据的类只应该是其他类的子程序。
在软件的历史中,粒度的增长带来软件开发的进步。语句-子程序-类-包等。
第七章:高质量子程序
a.子程序作用
1.子程序名提供逻辑抽象解释
2.避免重复代码
3.封装事务过程
.......
b.设计
内聚性:
功能内聚性:只完成一个功能
顺序内聚性:顺序执行的操作由上一步ans求下一步
通信内聚性:操作共享数据但无其他联系
临时内聚 :startup()等,不相关的操作组合在一起
逻辑内聚:通过传入的控制字段选择不同操作。如
inputAll(type)
对逻辑内聚:
不应该用一个程序控制另外一个程序的处理方式。
应把程序分为几个平行程序在上层调用。若有相似的底层操作,则封装成底层函数。
但如程序仅为if/case之内选择不同函数,就成了常用的事件处理器。
c.函数命名
避免使用含糊的词 如:HandleOutput->FormatAndPrint
找不到准确的词说明子程序可能需要修改
描述程序做的所有事 :一个动宾结构,object.function()则不必
或者描述程序的返回值
一个恰如其份但是糟糕的函数名说明需要重新设计
#######子程序长度一般应少于200行
d.参数
1.接口参数按一定顺序排列,如:修改-输入-输出型参数
考虑命名规则
2.使用自己函数定义的工作变量,如:
int workingVal=inputVal workingVal....... //注意这两个变量命名是很差的
3.尽量采用const关键字
4.以断言或注释解释参数的操作类型数值范围等
5.参数过多说明耦合紧密。人脑很难记住超过7个单词
7.确保形参实参一致
8.传递数据成员还是对象:
--取决于抽象
函数不要返回局部变量
e.宏程序
1.参数要套括号==
2.整个表达式外要套括号
3.多条语句外套{}
4.除非必要,还是不要用了吧...
第六部分:变量
代码被阅读的时间远远大于编写的时间,确保代码阅读方便。
一般事项
1.显式声明,初始化
2.就近声明和初始化
3.让变量的跨度和存活时间尽可能短以减少攻击窗口。(尽量不使用全局变量)
把相关的语句放在一起
提取语句成为单独的子程序
4.抛弃变量时赋不合理的NULL值
5.变量晚绑定值可以获得灵活性(使用具名变量)
6.单个变量只用于单一用途
7.检查是否有未使用的已声明变量
变量命名
1.8到16个字符
2.体现问题而非解决方案
3.一致的命名变量。
如revenueTotal---expenseAverage
例外numCustomers
4.采用对仗词如old-new,source-target
5.用比i,j,k更具意义的词为大循环或多重循环的循环变量命名
6.temp说明程序员并没有完全的搞懂问题。
7.done,found,error等布尔变量。
8.枚举类型使用组前缀。
一.命名规则
1.命名规则为代码增加了结构,是一项全局决策。
2.用g_标识全局变量
3.变量首字母小写,函数首字母大写。