- 短小
- 说明:20行的函数是最佳的。每一个函数只作一件事,而且函数都以顺序带到下一个函数,这就是函数应该到达的短小程度。
- 只作一件事
- 说明:函数应该只作一件事。作好一件事。只作这一件事。判断函数是否只作一件事,看是否还能在拆分出一个函数。
- 使用描述性的名称
- 说明:函数的名字正好描述了该函数所作的事,要作到见名知意。别惧怕长名称,长而具备描述性的名称,要比短而使人费解的名称好,要比描述性的长注释好。函数命名有个好办法,首先考虑应该给这个函数写上一句怎样的注释,而后想办法将注释变成函数的名称。
- 无反作用
- 函数承若只作一件事,可是隐藏作了另一些事,让人迷惑,致使古怪的时序性耦合及顺序依赖。
// 下面这个函数有“反作用”,有隐藏逻辑
public boolean isExpired(String key) {
if (currentTimes - begainTimes > MAX_EXPIRE_SECONDS) {
// 注意这个地方的delete是个隐藏逻辑
delete(key);
return true;
}
return false;
}
// 优化方式1:提炼判断逻辑,去除删除逻辑
public boolean isExpired(String key) {
if (currentTimes - begainTimes > MAX_EXPIRE_SECONDS) {
return true;
}
return false;
}
// 优化方式2:修改函数名称,让其名副其实
public boolean delKeyIfExpired(String key) {
if (currentTimes - begainTimes > MAX_EXPIRE_SECONDS) {
delete(key);
return true;
}
return false;
}
- 每一个函数一个抽象层级
- 说明:要确保函数只作一件事,函数中的语句都要在一个抽象级上。自顶向下读代码。
- 函数参数
- 说明:尽可能避免三个参数以上,参数越多测试覆盖全部可能的值的组合就越多,
若是参数过多就该将参数封装成类了。尽可能使用零参数函数,一参数函数,函数参数越多就越难理解。
public void doTask(Integer taskType, String value, Long taskId, Date createTime, String creater) {
// dosomething
}
// 优化:一个参数,之后再扩展参数也能够灵活添加,不用改接口
public void doTask(Task task) {
// dosomething
}
- 使用异常,不要返回错误码
- 说明:使用异常代替错误码,错误的处理代码就能从主路径代码中分离出来,获得简化。
// 假设出异常返回错误码,对异常逻辑当即处理,下面判断逻辑和嵌套逻辑就会很是复杂。
if (buildTask() == SUCCESS) {
if (buildIndex() == SUCCESS) {
if (doTask() == SUCCESS) {
if (releaseIndex()) {
log.error("releaseIndex success!!")
} else {
log.error("releaseIndex failed!!")
}
} else {
log.error("doTask failed!!")
}
} else {
log.error("buildIndex failed!!");
}
} else {
log.error("buildTask failed!!");
}
// 优化:错误处理代码从主路径中分离出来,这样就会简洁不少。
try {
buildTask();
buildIndex();
doTask();
releaseIndex();
} catch (Exception e) {
log.error("", e)
}
- 别重复本身
- 说明:若是过多的重复代码就应该抽取出来,消除冗余,减小重复。DRY,若是你们代码能作到这点,代码就会提高很多。
// 假设代码中有大量相似判断taskType作逻辑的,若是后面改了增长了一种类型也走之前逻辑,这样就要改N处,很容易漏掉
if (taskType in (START,PAUSE)) {
// dosomthing
}
// 优化:提炼公共逻辑,这样增长taskTyoe类型,只用修改一出地方
boolean isDoTasktype (Interger taskType) {
return taskType in (START,PAUSE,RELEASE,REMOVE);
}
// 优化:原有判断逻辑改成统一调用函数实现
if (isDoTasktype(taskType)) {
// dosomething
}
- 尽可能少用switch语句
- switch语句会致使如下问题:第一,会变的很长;第二,很容易违反单一权责原则(SRP);第三,很容易违反开闭原则(OCP)。简单的switch语句还好,复杂的语句能够经过策略模式来替代。
- 如何写出这样的函数
- 说明:一开始写函数都不会太完美,须要反复打磨、分解函数、修更名称、消除重复、测试。让函数更加短小,职责更加单一,命名更加合理。