系统越大,维护成本越高,这几乎是放之四海而皆准的真理。
其中一个原因:代码质量参差不齐。
持续优化代码、提高代码质量,是提供系统生命力的一个有效手段之一。
Think more, code less(思考越多,编码越少)
本文总结了
- General:通用
- Equal:平衡
- Short\Small:简短
- Simple:简单
GESSS原则
书面的表述: 短小精悍,平衡通用
李连杰演的神教教主,张三丰教他太极剑,太极拳。
天下武功:唯快不破,还有一个叫 无招胜有招
于是写代码,变成了美感审查。
何为美,大道至简、看着顺眼
,即对称、平衡、简洁:
- 看起来,一段一段Step 1、Step 2、Step 3
- 看起来,差不多,差不多的级别,差不多的大小
- 看到什么就是什么
- 看不到多余的
- 逻辑简洁。只看到1 + 1 = 2,不会看到1 + 1 != 3
用现成的可靠的 - 通用:G
- 通用工具函数,逻辑考虑周全,稳定性好
- 所及即所得,可读性强。
案例一:用现成的util,好用不费劲、还稳定
不建议写法:
theStr == null || theStr.equals("")
建议写法:
TextUtils.isEmpty(theStr)
看起来都差不多 - 平衡:E
- 函数块级 一般大小
- 判断语句,有排比句之势。
案例一:有一处拖沓了,紧一下
public void doFishing() {
//撒饵料,坐好
prepare();
//拉线
surduce();
//收网
// 很多很多代码
}
很显然,收网这部分的代码,是不一个层级的。看起来,突兀了。
放到一个函数里头去
public void doFishing() {
//撒饵料,坐好
prepare();
//拉线
suduce();
//收网
pullOut();
}
private void pullOut() {
// 收网 很多很多代码
}
案例二:人家都是method,我也要是
if ((mStr1 == null || mStr1.equals("")) || isPrepared(mStatus) || hasFishes()){
//doSomething
}
看起来,第一部分,应该收拢一下,放method中去。这样大家都是函数调用了。
if (TextUtils.isEmpty(mStr1) || isPrepared(mStatus) || hasFishes()){
//doSomething
}
长了看着累 - 简短:Short
在AS中,我用了ali-lint,规定函数超过80行后,就属于超大函数,需要进行拆分。
案例一:method内的逻辑有多个step,分批处理
public void doFishing() {
//撒饵料,坐好
//prepare几十行代码
//拉线
//surduce几十行代码
//收网
//pullOut几十行代码
}
改成
public void doFishing() {
//撒饵料,坐好
prepare()
//拉线
surduce();
//收网
pullOut();
}
private void prepare() {
// 撒饵料,坐好 很多很多代码
}
private void surduce() {
// 拉线 很多很多代码
}
private void pullOut() {
// 收网 很多很多代码
}
范例二:if else内的逻辑收拢
public void doFishing() {
//撒饵料,坐好
if (!hasFishHooked()) {
收线的代码 ------》整理成一个函数
} else {
继续放饵料,勾引 ------》整理成一个函数
}
}
范例三:判断条件 收拢
if ((判断1好几个) || (判断2好几个) || (判断3好几个)) {}
改进一下
if (判断1() || 判断2() || 判断3()) {}
范例四:method的入参有多余的,删掉
private void updateStatus(String status1, int statu2, int statusUnused) {
//更新状态
}
删掉多余的参数
private void updateStatus(String status1, int statu2) {
//更新状态
}
范例四:method的入参太多了
private void updateStatus(String status1, int statu2, int status3, int statu4, int statu5, int status6) {
//更新状态
}
太多了,看着累,并成一个bean
private void updateStatus(StatusBean bean) {
//更新状态
}
private class StatusBean {
private String status1, int statu2, int status3, int statu4, int statu5, int status6;
StatusBean(String status1, int statu2, int status3, int statu4, int statu5, int status6) {
//对Bean进行赋值,初始化
}
}
不要复杂,不要重复 - Simple:简单
案例一:删除不必要的if
public boolean isPassed(Double passRate) {
if (一堆判断 {
return true;
}
return false;
}
显然,不用这个if
public boolean isPassed(Double passRate) {
return 一堆判断;
}
案例二:删除不必要的else
public boolean isIllegal(int status) {
if (一堆判断 {
return 结果1;
} else {
return 结果2;
}
}
显然,不用这个else,可以减少一行代码
public boolean isIllegal(int status) {
if (一堆判断 {
return 结果1;
}
return 结果2;
}
案例三:删除不必要的变量
public boolean isIllegal(int status) {
Result res = doSomething(status);
List beans = res.toArray();
return beans;
}
单纯过渡一下,再砍掉一个,可以减少一行代码
public boolean isIllegal(int status) {
Result res = doSomething(status);
return res.toArray();
}
案例四:不要重复的
public void illegalize(int status) {
//根据status 做变换 step1 几十行
//根据status 做变换 step2 几十行
//根据status 做变换 step3 几十行
}
public void makePopular(int status) {
//根据status 做变换 step1 几十行
//根据status 做变换 step2 几十行
//根据结果,做最终变化 10行
}
step1、step2是一样的。或者类似的
public void illegalize(int status) {
changeStep1();
changeStep2();
//根据status 做变换 step3 几十行
}
public void makePopular(int status) {
changeStep1();
changeStep2();
//根据结果,做最终变化 10行
}
private void changeStep1() {
//根据status 做变换 step1 几十行
}
private void changeStep2() {
//根据status 做变换 step2 几十行
}
案例五:不要揉成一团
public int illegalize(int status) {
if (judge1()) {
if (judge2()) {
return newStatus;
}
}
return null;
}
逻辑揉在一起,显然不合理
public int illegalize(int status) {
if (!judge1()) {
return null;
}
if (!judge2()) {
return null;
}
return newStatus;
}
案例六:null是地雷
public List getUsers(int status) {
if (!isLegal(status)) {
return null;
}
//doSomething
return result;
}
能不返回null,就别返回null了。
public List getUsers(int status) {
if (!isLegal(status)) {
return new List(0);
}
//doSomething
return result;
}
总结来说
网上也有很多这样,那样的代码规范。很多人不是不知道,而是一下子想不起来。
忘记了这些有形的招式,才能融汇到自身。