函数
1.越短小越好
- if/else/while语句的代码块应该只有一行,该行应该是一个函数调用语句。
- 函数的缩进层级不应该多于一层或两层。
2.只做一件事
- 如果函数只是做了该函数名下同一抽象层上的步骤,则函数只做了一件事。
- 要判断函数是否不止做了一件事,就是要看是否能再拆出一个函数。
3.每个函数一个抽象层级 4.switch语句
- 把switch埋在较低的抽象层级,一般可以放在抽象工厂底下,用于创建多态对象。
5.使用描述性的名称
- 函数越短小、功能越集中,就越便于取个好名字。
- 别害怕长名称,长而具有描述性的名称,要比短而令人费解的名称好,要比描述性的长注释好。
- 别害怕花时间取名字。
6.函数参数
- 参数越少越好,0参数最好,尽量避免用三个以上参数
- 参数越多,编写组合参数的测试用例就越困难
- 别用标识参数,向函数传入bool值是不好的,这意味着函数不止做一件事。可以将此函数拆成两个。
- 如果函数需要两个、三个或者三个以上参数,就说明其中一些参数应该封装成类了。
- 将参数的顺序编码进函数名,减轻记忆参数顺序的负担,例如,assertExpectedEqualsActual(expected, actual)
7.副作用(函数在正常工作任务之外对外部环境所施加的影响)
- 检查密码并且初始化session的方法 命名为checkPasswordAndInitializeSession而非checkPassword,即使违反单一职责原则也不要有副作用
- 避免使用"输出参数",如果函数必须修改某种状态,就修改所属对象的状态吧
8.设置(写)和查询(读)分离
- if(set("username", "unclebob")) { ... } 的含义模糊不清。应该改为:if (attributeExists("username")) { setAttribute("username", "unclebob"); ... }
9.使用异常代替返回错误码
- 返回错误码会要求调用者立刻处理错误,从而引起深层次的嵌套结构:if (deletePate(page) == E_OK) { if (xxx == E_OK) { if (yyy == E_OK) { log; } else { log; } } else { log; } } else { log; }
- 使用异常机制:try { deletePage; xxx; yyy; } catch (Exception e) { log(e->getMessage);
- try/ catch代码块丑陋不堪,所以**最好把 try和 catch代码块的主体抽离出来,单独形成函数**
try{
do;
} catch(Exception e) {
handle;
}
- 函数只做一件事,错误处理就是一件事。如果关键字try在某个函数中存在,它就该是函数的第一个单词,而且catch代码块后面也不该有其他内容。
- 定义错误码的class需要添加新的错误码时,所有用到错误码class的其他class都得重新编译和部署。但如果使用异常而非错误码,新异常可以从异常class派生出来,无需重新编译或部署。这也是开放闭合原则(对扩展开放,对修改封闭)的范例。
10.不要写重复代码
- 重复是软件中一切邪恶的根源。当算法改变时需要修改多处地方
11.结构化编程
- 只要函数保持短小,偶尔出现的return、break、continue语句没有坏处,甚至还比单入单出原则更具有表达力。goto只有在大函数里才有道理,应该尽量避免使用。
12.如何写出这样的函数
- 并不需要一开始就按照这些规则写函数,没人做得到。想些什么就写什么,然后再打磨这些代码,按照这些规则组装函数。