通用代码技巧

最后更新于:2022-04-02 03:10:46

[TOC] > [参考](http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy) ## 读代码的次数要多与写代码 所有不要了强行精简,而丧失语义 ## 不要做复杂的复用 共同点少于不同点,则写两个函数 error ``` void foo() { if (getOS().equals("MacOS")) { a(); } else { b(); } c(); if (getOS().equals("MacOS")) { d(); } else { e(); } } ``` good ``` void fooMacOS() { a(); c(); d(); } //和 void fooOther() { b(); c(); e(); } ``` ## 提取相同部分 error ``` void foo() { a(); b() c(); if (getOS().equals("MacOS")) { d(); } else { e(); } } ``` good ``` void preFoo() { a(); b() c(); } void fooMacOS() { preFoo(); d(); } void fooOther() { preFoo(); e(); } ``` ## 何时需要注释 好的代码是不需要写逻辑注释的,只需要写业务注释 ## 局部变量可简单 error ``` boolean successInDeleteFile = deleteFile("foo.txt"); if (successInDeleteFile) { ... } else { ... } ``` good ``` boolean success = deleteFile("foo.txt"); if (success) { ... } else { ... } ``` ## 不要重用局部变量 error ``` String msg; if (...) { msg = "succeed"; log.info(msg); } else { msg = "failed"; log.info(msg); } ``` good ``` if (...) { String msg = "succeed"; log.info(msg); } else { String msg = "failed"; log.info(msg); } ``` ## 把复杂的逻辑提取出去,做成“帮助函数” error ``` //code // put elephant1 into fridge2 openDoor(fridge2); if (elephant1.alive()) { } else { } closeDoor(fridge2); //code ``` good ``` void put(Elephant elephant, Fridge fridge) { openDoor(fridge); if (elephant.alive()) { } else { } closeDoor(fridge); } //code put(elephant1, fridge2); //code ``` ## 在合理的地方换行 error ``` if (someLongCondition1() && someLongCondition2() && someLongCondition3() && someLongCondition4()) { ... } ``` good ``` if (someLongCondition1() && someLongCondition2() && someLongCondition3() && someLongCondition4()) { ... } ``` ## 避免使用自增减表达式 如 `(i++,++i,i–,–i)` ``` //error foo(i++) //good int t = i; i += 1; foo(t); ``` ``` //error foo(++i) //good i += 1; foo(i); ``` 自增在 一下两种可正常使用 1. `for(int i = 0; i < 5; i++)` 2. 单独写层一行 `i++` ## 不要在条件语句时,省略大括号 error ``` if (...) action1(); ``` 由于花括号的存在,使得代码界限明确,让眼睛负担更小了 ## 合理使用括号,不要依赖操作符 `1 + 2 * 3` ok `2 << 7 - 2 * 3` error `2 << (7 - 2 \* 3)`good ## 避免使用continue和break 循环语句(for,while)里面出现return是没问题的,然而如果你使用了continue或者break,就会让循环的逻辑和终止条件变得复杂,难以确保正确 1. 如果出现了continue,你往往只需要把continue的条件反向,就可以消除continue。 2. 如果出现了break,你往往可以把break的条件,合并到循环头部的终止条件里,从而去掉break。 3. 有时候你可以把break替换成return,从而去掉break。 4. 如果以上都失败了,你也许可以把循环里面复杂的部分提取出来,做成函数调用,之后continue或者break就可以去掉了。 案例1: error ``` List goodNames = new ArrayList<>(); for (String name: names) { if (name.contains("bad")) { continue; } goodNames.add(name); ... } ``` good ``` List goodNames = new ArrayList<>(); for (String name: names) { if (!name.contains("bad")) { goodNames.add(name); ... } } ``` 案例2: error ``` while (condition1) { ... if (condition2) { break; } } ``` good ``` while (condition1 && !condition2) { ... } ``` 案例3: error ``` public boolean hasBadName(List names) { boolean result = false; for (String name: names) { if (name.contains("bad")) { result = true; break; } } return result; } ``` good ``` public boolean hasBadName(List names) { for (String name: names) { if (name.contains("bad")) { return true; } } return false; } ``` ## 写直观的代码 error ``` if (action1() || action2() && action3()) { ... } ``` good ``` if (!action1()) { if (action2()) { action3(); } } ``` ## 不漏下所有的条件 由于疏忽而漏掉的分支,全都会自动“掉下去”,最后返回意想不到的结果 error ``` if (...) { if (...) { ... return false; } } else if (...) { ... return false; } return true; ``` good ``` if (...) { if (...) { ... return false; } else { return true; } } else if (...) { ... return false; } else { return true; } ``` ## 不省略缺失值 error ``` String s = ""; if (x < 5) { s = "ok"; } ``` good ``` String s; if (x < 5) { s = "ok"; } else { s = ""; } ``` ok(如果请情况简单) ``` String s = x < 5 ? "ok" : ""; ``` ## 错误处理 不要漏掉任何一个可能返回错误的 error 如果foo和bar都可能产生异常A,你的代码应该尽可能写成 error ``` try { foo(); bar(); } catch (A e) {...} ``` good ``` try { foo(); } catch (A e) {...} try { bar(); } catch (A e) {...} ``` ## 处理 null 当 find 返回 null 时候,需要对 null 有意义的处理 error ``` public String foo() { String found = find(); if (found == null) { return null; } } ``` good ``` public String foo() { String found = find(); if (found == null) { //code } } ```
';