欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

美化java代碼,從合理注釋開始

 更新時間:2019年06月06日 08:56:18   作者:連理枝_  
在Java的編寫過程中我們需要對一些程序進行注釋,除了自己方便閱讀,更為別人更好理解自己的程序,可以是編程思路或者是程序的作用,總而言之就是方便自己他人更好的閱讀。下面我們來一起學習一下吧

請停止代碼注釋

“干凈的代碼應該像寫好的散文一樣” - Robert C. Martin

不良代碼的通病就是有很多注釋。這是凌亂的源代碼最明顯的跡象。

每個程序員的目標應該是編寫干凈和富有表現(xiàn)力的代碼,以避免代碼注釋。每個變量,函數(shù)和類的目的應該隱含在其名稱和結(jié)構中。

當其他人讀取您的代碼時,他們不應該閱讀注釋以了解你的代碼正在做什么。命名良好的類和函數(shù)應該引導讀者通過你的代碼,就像一本寫得很好的小說一樣。當讀者看到一個新的類或功能時,他們不應該對他們在里面看到的東西感到困惑難以理解。

請記住,開發(fā)人員的工作時間很少花在編寫代碼上,花在閱讀代碼和理解代碼上的時間要多得多。

注釋掩飾錯誤

在代碼中命名是非常重要的。您應該花費大量精力準確而精確地命名每一段代碼,以便其他開發(fā)人員能夠理解您的代碼。

// 按狀態(tài)查找員工
List<Employee> find(Status status) {
...
}

在此示例中,名稱find不夠描述,因此此函數(shù)的作者需要留下描述函數(shù)功能的描述性注釋。當我們看到從另一個模塊調(diào)用的find函數(shù)時,它的作用是一個謎。它發(fā)現(xiàn)了什么?究竟是什么意思?它返回了它發(fā)現(xiàn)的東西嗎?怎么找到它發(fā)現(xiàn)的東西?就像鮑勃叔叔在他的書《Clean Code》中所說,如果你需要寫注釋,你就無法通過代碼表達自己真實的用意。

我們不希望檢查每個函數(shù)上面的注釋,以了解它的作用。

List<Employee> getEmployeesByStatus(Status status) {
...
}

現(xiàn)在很明顯能看出來這個函數(shù)的具體作用,這使得注釋變得多余。這讓我想到了注釋糟糕的下一個方式。

冗余注釋

這些混亂了你的代碼,完全沒必要。

//此函數(shù)發(fā)送電子郵件
void sendEmail() {
...
}
//此函數(shù)發(fā)送電子郵件
public class Employee {
...
}
/ **
* @param title CD的標題
* @param作者CD的作者
* @param track CD上的曲目數(shù)
* /
public void addCd(String title, String author, int tracks) {
...
}

多數(shù)情況是強制冗余。很多公司在每個功能和類別上都要求這一點。如果你的上司要求這樣做,請他們不要。

錯誤的抽象程度

如果您有一個很長的功能或需要記錄代碼的哪一部分做了什么,那么您可能違反了這些規(guī)則:

1.功能應該做一件事。

2.功能應該很小。

這是一個例子

//此函數(shù)計算價格,與銷售額進行比較
//促銷,檢查價格是否有效,然后
//向用戶發(fā)送促銷電子郵件
public void doSomeThings(){
//計算價格
...
...
...

//將計算出的價格與促銷活動進
...
...
...

//檢查計算的價格是否有效
...
...
...

//向用戶發(fā)送促銷信息
...
...
...
}

當你成功地將邏輯的每個部分封裝到一個單獨的函數(shù)中時,代碼不需要注釋就會表現(xiàn)的應該像它的作用描述一樣。

重構如下:

public void sendPromotionEmailToUsers(){
calculatePrices();
compareCalculatedPricesWithSalesPromotions();
checkIfCalculatedPricesAreValid();
sendPromotionEmail();
}

而不是注釋代碼的每個部分,每個邏輯塊應該很好地封裝在它自己的函數(shù)中。

首先,這提高了可讀性。每個代碼塊不必逐行讀取。我們可以簡單地讀取輔助函數(shù)名稱并理解它的作用。如果我們想要了解每個函數(shù)內(nèi)部的更多細節(jié),就能去看具體實現(xiàn)。

其次,它提高了可測試性。在上面的示例中,我們可以為每個函數(shù)單獨進行單元測試。如果不封裝這些單獨的函數(shù),則很難測試較大函數(shù)sendPromotionEmailToUsers()的每個部分。執(zhí)行多個功能的功能很難測試。

最后,它提高了可重構性。通過將邏輯的每個部分封裝到自己的函數(shù)中,將來更改維護更容易,并且單獨功能的函數(shù)會被隔離以僅更改該函數(shù)的行為。當我們使用局部變量的長函數(shù)在整個函數(shù)中持續(xù)存在時,由于函數(shù)的緊耦合,很難在不導致其他地方變化的情況下重構函數(shù)。

注釋掉的代碼

注釋掉的代碼應該被視為roadkill。不要看它,不要聞它,不要問它從哪里來,只是擺脫它。保持它的時間越長,其余代碼聞到的時間就越長......

/ *
public void oldFunction(){
noOneRemembersWhyIAmHere();
tryToUnCommentMe();
iWillProbablyCauseABuildFailure();
HAHAHA();
}
* /

盡管刪你不刪別人更不敢刪。如果你以后需要它,你可以隨時檢查版本控制系統(tǒng),因為你肯定用了VCS,對嗎?(如果不是當我沒說)

TODO注釋

不要寫TODO注釋,而不僅僅是......做到了嗎?大多數(shù)時候這些注釋都會被遺忘,后來可能變得無關或錯誤。當另一個程序員稍后看到TODO注釋時,他們?nèi)绾沃朗欠襁€需要這樣做?

不過偶爾TODO注釋是好的,如果你正在等待另一個隊友的合并(一般不會太久)。就可以這么做,直到你可以進行修復并提交它。

“當你覺得有必要寫注釋時,首先要嘗試重構代碼,以便任何注釋都變得多余?!?- Martin Fowler

注釋的謊言

當Jimmy在他寫的新功能上面打上注釋時,他認為他正在幫助任何看到他的代碼的未來開發(fā)人員。其實呢他真正在做的是設置一個陷阱。他的注釋可能是彌天大謊(沒有雙關語意圖)蟄伏數(shù)月或數(shù)年沒有被觸及,只是等待成為一個令人討厭的陷阱。然后有一天,在數(shù)百個重構和需求變更之一中,他的注釋從一些遙遠的模塊中失效,但是仍然在錯誤的引導著無數(shù)的接盤俠。

當你更改一行代碼時,你怎么知道你更改的代碼會不會使其他地方的注釋無效?沒有辦法知道

public class User {
...
//它包含用戶的名字和姓氏
String name;
...
}

然后,需求更改,他們希望將名稱拆分為firstName和lastName。

public class User {
...

// 它包含用戶的名字和姓氏
String firstName;
String lastName;

...
}

注釋現(xiàn)在已經(jīng)錯了。你可以更新注釋以反映更改,但是你是否真的想在每次更改后手動維護所有注釋?你是開發(fā)人員,而不是文檔。

但是這個注釋很容易被注意到并且沒有問題需要改變。但是你很難保證在程序的其他地方,會不會也注釋了這個參數(shù)name是用戶的名字和姓氏。更改一小塊地方的代碼,可能會讓很多的代碼注釋都失效。

讓我們看另一個例子:

//根據(jù)狀態(tài)處理員工
void processEmployees(){
...
List < Employee > employees = findEmployees(statusList);
...
}

//這會按狀態(tài)列表查找Employees
List < Employee > findEmployees(List < String > statusList){
...
}

然后有人被要求更改函數(shù)findEmployees,以便通過名稱列表而不是狀態(tài)列表查找員工。

//根據(jù)狀態(tài)處理員工
void processEmployees(){
...
List < Employee > employees = findEmployees(statusList);
...
}

//這會按狀態(tài)列表查找Employees
List < Employee > findEmployees(List < String > nameList){
...
}

首先,上面的注釋findEmployees已經(jīng)失效,因此需要更改。沒問題,對吧?錯了。

processEmployees上面的注釋也已失效,因此也需要更改。還有多少其他評論被這個小型重構改成無效?這一次更改在源代碼中創(chuàng)建了多少注釋謊言?

替代方案:

void processEmployees(){
...
List < Employee > employees = findEmployeesByName(nameList);
...
}

List < Employee > findEmployeesByName(List < Name > nameList){
...
}

如果你準確而準確地命名你的函數(shù),則不需要注釋,并且你不會在代碼中散布謊言。

“代碼永遠不會說謊,注釋會。” - 羅恩杰弗里斯

什么時候需要注釋呢

我知道很多開發(fā)人員都是代碼注釋的死硬支持者,對他們來說,我必須承認有時注釋是可以的。不過你每寫一段都應當有充足的理由

復雜表達式

如果您有復雜的SQL或正則表達式語句,請繼續(xù)編寫注釋。在代碼中干凈利落地表達諸如此類的陳述可能很困難。在這些表達式上面添加注釋可以幫助其他開發(fā)人員更好地理解您的代碼。

// 格式匹配kk:mm:ss EEE,MMM dd,yyy
Pattern timePattern = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w*, \\d*, \\d*");

注釋警告

如果你需要警告其他開發(fā)人員這段代碼可能發(fā)生的bug,可以在此代碼附近留下注釋。這些注釋可以充當代碼中神秘行為的先兆,并為你的代碼增加價值。

意圖澄清

如果你實在命名廢,那就要為你沒有能力寫出富有表現(xiàn)力的代碼而負責,并寫下注釋表明自己的意圖。

如果你必須撰寫注釋,請確保它是本地的。遠離其引用的非本地評論注定會失效并變成謊言。引用函數(shù)或變量的注釋應直接位于其上方。警告注釋可以在它引用的代碼的上方或旁邊。如果您的IDE支持注釋突出顯示,請使您的警告注釋從其余代碼中脫穎而出。

最后

我已經(jīng)建立了對代碼注釋的感受。我鄙視他們,但我知道有時他們是需要的。

所以,請停止寫這么多注釋。

本文是作者在推特上看到國外一位大神 布萊恩·諾蘭德 的論述,深以為然因此翻譯后加以修飾進行分享的。希望今后自己的代碼也能像散文一樣優(yōu)雅。

相關文章

最新評論