有时把代码重复的逻辑封装成方法会显得更优雅和语义化

27 阅读2分钟

很多人写代码为了快速交付,直接复制相似的代码和局部的一两行代码,并未充足考虑到未来后人如何修改这段代码,是否会给后人留坑,没有给予整个类或工程的角度审视有哪些代码是应该复用,哪些应该开辟新分支,本文以一个很简单的案例讲解避免重复代码的效果和意义。

案例:缓存读写时经常会用业务字段增加前缀去拼接一个缓存key

public FakeObj getFakeObj(Integer bizId) {
    // ...
    String cacheKey = "orderId:" + bizId;
    // ...
}

public boolean putFakeObj(Integer bizId, FakeObj fakeObj) {
    // ...
    String cacheKey = "orderId:" + bizId;
    // ....
}

public boolean deleteFakeObj(Integer bizId) {
    // ...
    String cacheKey = "orderId:" + bizId;
    // ....
}

上面的代码每个方法中都有一行是用来构造缓存key的,虽然构造缓存key是一个很简单且只有一行的代码,但这个拼接缓存key的逻辑重复了3行。

这种写法有2个问题:

  1. 如果哪一天需要修改这个缓存key构造方式时,就需要修改3处。这种写法并不优雅
  2. 由于orderId常量需要写多次,如果某一次拼写错误,则很难被发现

如果把拼接缓存key的那一行当成是一个逻辑,那么它更适合提取成一个private方法,尽管这个方法只有一行,修改后如下:

public FakeObj getFakeObj(Integer bizId) {
    // ...
    String cacheKey = buildFakeCacheKey(bizId);
    // ...
}

public boolean putFakeObj(Integer bizId, FakeObj fakeObj) {
    // ...
    String cacheKey = buildFakeCacheKey(bizId);
    // ....
}

public boolean deleteFakeObj(Integer bizId) {
    // ...
    String cacheKey = buildFakeCacheKey(bizId);
    // ....
}

private String buildFakeCacheKey(Integer bizId) {
    return "orderId:" + bizId;
}

虽然总行数变多了,但是代码语义更清晰了,看代码就像阅读一样。

建议

  1. 只要重复代码超过1处被使用,那么它就应该提取成一个方法或临时变量,并给他取一个有含义的方法名或变量名。
  2. 避免重复代码,是在积功德!

(如果你使用IDE,比如:idea,可以选中重复的代码,右键从refactor中选择合适的选项,让idea帮你写好代码,风险很低)