如何提高代碼的可閱讀行
好的代碼書寫規(guī)范會讓你在閱讀的時候很清晰明了的知道業(yè)務(wù)的邏輯和處理流程。當(dāng)你閱讀高質(zhì)量的代碼時候,可以讓你心曠神怡。哇還可以這么寫,這樣寫簡潔又大方,命名規(guī)范又容易理解.....
軟件系統(tǒng)生命周期80%的時間都是閱讀和維護(hù)代碼,可讀性好的代碼會讓我們在維護(hù)的時候事半功倍,提高工作效率,更快的梳理出需要改動的地方??赡墚?dāng)開始做的時候不習(xí)慣,覺得麻煩,但是當(dāng)我們堅持一段時間,效果就會顯而易見。
下面我總結(jié)幾方面的在提高代碼可讀性方面我們能做到或者加以改進(jìn)的地方。
1.變量,方法類的命名要表達(dá)清晰明了
在方便變量命名的時候我們使用的單詞不要過于簡單,用一些有表達(dá)力的單詞。示例如下
| 單詞 | 可替代單詞 |
|---|---|
| send | dispatch deliver distribute |
| find | search locate extract |
| start | launch create begin |
| make | add new generate create build set up |
在做循環(huán)迭代器的時候,避免使用i,j,k等過于簡單的變量命名,userIndex、memberIndex這種名字會更有表達(dá)力。因為循環(huán)層次越多,代碼越難理解,有表達(dá)力的迭代器名字可讀性會更高。
為名字添加形容詞等信息能讓名字更具有表達(dá)力,但是名字也會變長。名字長短的準(zhǔn)則是:作用域越大,名字越長。因此只有在短作用域才能使用一些簡單名字。
2.重視代碼規(guī)范
在定義類的成員變量的時候,通過加前綴來區(qū)分不同作用域的代碼。
例如
- 加s表示靜態(tài)成員變量
- 加m表示私有成員變量
- 靜態(tài)常量大寫,單詞之間用_區(qū)分
- 命名遵循大小駝峰原則
private static MyClass sSingleton;
int mPackagePrivate;
private int mPrivate;
3.名字不能有歧義
起完名字要思考一下別人會對這個名字有何解讀,會不會誤解了原本想表達(dá)的含義。
布爾相關(guān)的命名加上 is、can、should、has 等前綴,可以方便的看到判斷結(jié)果。
4.代碼格式規(guī)范
代碼縮進(jìn)可以增強(qiáng)代碼的可閱讀性,代碼縮進(jìn)一般為4個空格。
-
如果句子過長需要換行,或者我們在使用RxJava等框架的鏈?zhǔn)秸{(diào)用的時候,建議使用 以下規(guī)范。
第二行相對第一行縮進(jìn) 4 個空格,從第三行開始,不再繼續(xù)縮進(jìn),參考示例。
運(yùn)算符與下文一起換行。
方法調(diào)用的點符號與下文一起換行。
方法調(diào)用時,多個參數(shù),需要換行時,在逗號后進(jìn)行。
client.newCall(new Request.Builder()
.url(address)
.build())
.enqueue(new Callback() {
@Override
ublic void onFailure(Call call, IOException e) {
}
5.注釋
注釋本應(yīng)作為代碼不可分割一部分,因為它是對代碼最直觀最詳細(xì)的說明,你可以把設(shè)計思路、用法和注意事項都寫在注釋里面,這樣無論是對你自己還是對別人都是有好處的,它讓你能在很久沒有接觸代碼的時候快速回憶起當(dāng)初的想法,能讓閱讀源碼的人更快理解你的思路,讓使用的人更清楚用法。
復(fù)雜邏輯寫清楚實現(xiàn)的步驟
方法注釋清楚方法的作用
6. 使用 Builder 代替構(gòu)造方法
當(dāng)某個類的構(gòu)造方法有很多個參數(shù)或者有很多個重載版本時,我們應(yīng)該考慮為這個類寫一個 Builder,通過這個 Builder 創(chuàng)建配置并創(chuàng)建該類的實例。
假設(shè)我們有個類用來代表一個矩形,它的名字叫做 Rectangle,它的代碼如下所示:
public class Rectangle {
private int mId;
private int mWidth;
private int mHeight;
private int mStroke;// 邊框?qū)挾?
public Rectangle(int id) { ... }
public Rectangle(int id, int width, int height) { ... }
public Rectangle(int id, int width, int height, int stroke) { ... }
}
于是我們就可能看見這樣的代碼 new Rectangle(1, 1, 1, 1),這樣的代碼可讀性是很差的,因為我們無法一眼就看出這個矩形設(shè)置了哪些信息,還需要去查閱下相關(guān)的 API 文檔。此外,當(dāng)我們需要創(chuàng)建一個只需指定 id 和 stroke 的矩形的時候,我們就必須再寫一個新的構(gòu)造方法,當(dāng)一個對象的屬性較多的時候,構(gòu)造方法的重載版本就可能變得非常的多,維護(hù)成本也隨之提高。如果我們?yōu)?Rectangle 創(chuàng)建一個 Builder,通過 Builder 創(chuàng)建矩形實例的過程就會變得靈活而清晰很多:
public class Rectangle {
private int mId;
private int mWidth;
private int mHeight;
private int mStroke;// 邊框?qū)挾?
private Rectangle(Builder builder) {
mId = builder.id;
mWidth = builder.width;
mHeight = builder.height;
mStroke = builder.stroke;
}
public static class Builder {
private int id;
private int width;
private int height;
private int stroke;// 邊框?qū)挾?
public Builder(int id) {
this.id = id;
}
public Rectangle build() {
return new Rectangle(this);
}
public Builder width(int width) {
this.width = width;
return this;
}
public Builder height(int height) {
this.height = height;
return this;
}
public Builder stroke(int stroke) {
this.stroke = stroke;
return this;
}
}
}
現(xiàn)在,我們創(chuàng)建 Rectangle 實例的過程就會變成下面的樣子,它不僅讓我們一眼就看出矩形設(shè)置了哪些屬性,而且我們還可以自由組合這些屬性,達(dá)到重載構(gòu)造方法想要的結(jié)果:
Rectangle.Builder builder1 = new Rectangle.Builder(1);
Rectangle rect1 = builder1.width(1).height(1).stroke(1).build();
Rectangle.Builder builder2 = new Rectangle.Builder(2);
Rectangle rect2 = builder2.width(1).height(1).build();
Rectangle.Builder builder3 = new Rectangle.Builder(3);
Rectangle rect3 = builder3.stroke(1).build();
這個涉及到設(shè)計模式里面的建造者模式,后續(xù)可以了解一下。
7.函數(shù)設(shè)計盡量功能單一
自己以前為了方便,在開發(fā)的時候經(jīng)常將函數(shù)寫成一大片,在后期的維護(hù)和二次優(yōu)化上面需要花很多時間。當(dāng)然很多不是一蹴而就的,我們需要不斷的花時間去思考,這樣自己才能不斷進(jìn)步。