函数规范

1. 短小

说明:20行的函数是最佳的。每个函数只做一件事,并且函数都以顺序带到下一个函数,这就是函数应该到达的短小程度。

2. 只做一件事

说明:函数应该只做一件事。做好一件事。只做这一件事。判断函数是否只做一件事,看是否还能在拆分出一个函数。

3. 使用描述性的名称

说明:函数的名字正好描述了该函数所做的事,要做到见名知意。别害怕长名称,长而具有描述性的名称,要比短而令人费解的名称好,要比描述性的长注释好。函数命名有个好办法,首先考虑应该给这个函数写上一句怎样的注释,然后想办法将注释变成函数的名称。

4. 无副作用

说明:函数承若只做一件事,但是隐藏做了另外一些事,让人迷惑,导致古怪的时序性耦合及顺序依赖。

// 下面这个函数有“副作用”,有隐藏逻辑
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;
}

5. 每个函数一个抽象层级

说明:要确保函数只做一件事,函数中的语句都要在一个抽象级上。自顶向下读代码。

6. 函数参数

说明:尽量避免三个参数以上,参数越多测试覆盖所有可能的值的组合就越多,
如果参数过多就该将参数封装成类了。尽量使用零参数函数,一参数函数,函数参数越多就越难理解。

public void doTask(Integer taskType, String value, Long taskId, Date createTime, String creater) {
    // dosomething
}

// 优化:一个参数,以后再扩展参数也可以灵活添加,不用改接口
public void doTask(Task task) {
    // dosomething
}

7. 使用异常,不要返回错误码

说明:使用异常代替错误码,错误的处理代码就能从主路径代码中分离出来,得到简化。

// 假设出异常返回错误码,对异常逻辑立即处理,下面判断逻辑和嵌套逻辑就会非常复杂。
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)
}

8. 别重复自己

说明:如果过多的重复代码就应该抽取出来,消除冗余,减少重复。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
}

9. 尽量少用switch语句

说明:switch语句会导致以下问题:第一,会变的很长;第二,很容易违反单一权责原则(SRP);第三,很容易违反开闭原则(OCP)。简单的switch语句还好,复杂的语句可以通过策略模式来替代。

10. 如何写出这样的函数

说明:一开始写函数都不会太完美,需要反复打磨、分解函数、修改名称、消除重复、测试。让函数更加短小,职责更加单一,命名更加合理。
posted @ 2019-06-18 18:51  wudiffs  阅读(599)  评论(2编辑  收藏  举报