幾個(gè)友好Java代碼習(xí)慣建議
我工作多年,遇到過(guò)各種各樣的同事。我見(jiàn)過(guò)各種代碼,優(yōu)秀的、垃圾的、沒(méi)有吸引力的等等,所以這篇文章記錄了一個(gè)優(yōu)秀的Java開(kāi)發(fā)應(yīng)該具備哪些良好的開(kāi)發(fā)習(xí)慣或最佳實(shí)踐。
1、封裝方法參數(shù)
當(dāng)你的方法參數(shù)過(guò)多時(shí),建議封裝一個(gè)對(duì)象。下面是反面教材,誰(shuí)教你寫(xiě)成這樣的代碼?
public void updateX(long num, String str1, String str2, String str3, String str4, String str5, String str6) {}
盡量把這些輸出封裝到一個(gè)對(duì)象中。
public class X { private Long num; private String str1; ...}
為什么要這樣寫(xiě)?例如,您的方法用于查詢(xún)。如果以后添加查詢(xún)條件,需要修改方法嗎?每次添加時(shí)必須更改方法參數(shù)列表。封裝一個(gè)對(duì)象,以后無(wú)論添加多少查詢(xún)條件,只需要給對(duì)象添加字段即可。關(guān)鍵是代碼看起來(lái)也很舒服!
2、封裝業(yè)務(wù)邏輯
如果你看過(guò)“狗屎山”,你會(huì)有很深的感受。這樣的方法可以寫(xiě)幾千行代碼,沒(méi)有什么規(guī)則可言。經(jīng)常負(fù)責(zé)人會(huì)說(shuō),這個(gè)業(yè)務(wù)太復(fù)雜了,沒(méi)辦法改進(jìn),是偷懶的借口。無(wú)論業(yè)務(wù)多么復(fù)雜,我們都可以通過(guò)合理的設(shè)計(jì)和封裝來(lái)提高代碼的可讀性。下面是一個(gè)建議的代碼。
void clearBills(Long customerId) { //獲取清算所需的票據(jù)ng ClearContext context = getClearContext(customerId); // 驗(yàn)證該金額是否合法 checkAmount(context); // 確定優(yōu)惠券是否可用,并返回可扣除金額 CouponDeductibleResponse deductibleResponse = couponDeducted(context); // 結(jié)清所有賬單 DepositClearResponse response = clearBills(context); // 發(fā)送還款對(duì)賬消息 repaymentService.sendVerifyBillMessage(customerId, context.getDeposit()); // 更新帳戶(hù)余額 accountService.clear(context, response); // 處理已清算的息票,用完或未綁定 couponService.clear(deductibleResponse); // 保存優(yōu)惠券扣減記錄 clearCouponDeductService.add(context, deductibleResponse);}
這段代碼中的業(yè)務(wù)非常復(fù)雜。估計(jì)內(nèi)部保守做了一萬(wàn)件事情,但是不同層次的人寫(xiě)的東西完全不一樣。不得不贊這個(gè)業(yè)務(wù)的拆分,方法的封裝。大企業(yè)中有多個(gè)小企業(yè)。不同的業(yè)務(wù)可以調(diào)用不同的服務(wù)方法。
接手的人即使沒(méi)有流程圖等相關(guān)文件,也能快速了解業(yè)務(wù)。初級(jí)開(kāi)發(fā)寫(xiě)的很多業(yè)務(wù)方法都是上一行代碼給業(yè)務(wù)A,下一行代碼給業(yè)務(wù)B,下一行代碼給業(yè)務(wù)A。還有一堆單元邏輯嵌套在業(yè)務(wù)之間調(diào)用,這非?;靵y并且有很多代碼。
3、判斷集合類(lèi)型不為空的正確方法
很多人喜歡寫(xiě)這樣的代碼來(lái)判斷集合。
if (list == null || list.size() == 0) { return null;}
當(dāng)然,如果你堅(jiān)持這樣寫(xiě)是沒(méi)有問(wèn)題的。
org.springframework.util.CollectionUtils但是你不覺(jué)得不舒服嗎,現(xiàn)在框架中的任何一個(gè)jar包都有一個(gè)收集工具類(lèi),比如com.baomidou.mybatisplus.core.toolkit.CollectionUtils. 以后請(qǐng)這樣寫(xiě)。
if (CollectionUtils.isEmpty(list)) { return null;}
4、集合類(lèi)型返回值不返回null
當(dāng)你的業(yè)務(wù)方法返回一個(gè)集合類(lèi)型時(shí),請(qǐng)不要返回null,正確的操作是返回一個(gè)空集合??匆幌耺ybatis的列表查詢(xún)。如果沒(méi)有查詢(xún)?nèi)魏卧?,它將返回一個(gè)空集合而不是 null。否則,調(diào)用者必須做NULL判斷,大多數(shù)情況下對(duì)象也是如此。
5、推薦使用lombok
當(dāng)然,這是一個(gè)有爭(zhēng)議的問(wèn)題,我的習(xí)慣是使用它來(lái)省略 getter、setter、toString 等。使用Lombok。
6、編寫(xiě)盡可能少的工具
為什么要少寫(xiě)一些工具類(lèi),因?yàn)槟銓?xiě)的大部分工具類(lèi)都包含在你引入的jar包中,比如String、Assert斷言、IO上傳文件、復(fù)制流、Bigdecimal]等等。編寫(xiě)自己的錯(cuò)誤并加載冗余類(lèi)很容易。
7、寫(xiě)有意義的方法注釋
寫(xiě)這種注釋是不是怕后來(lái)接手的人瞎了。
要么不要寫(xiě)它,要么只是在它之后添加一個(gè)描述。寫(xiě)這樣的注釋并從IDEA收到一堆警告很痛苦。
/*** 請(qǐng)求號(hào)碼驗(yàn)證** @param a* @param b* @param param* @return Result*/
8、盡量不要讓IDEA報(bào)警
很反感在IDEA代碼窗口看到一連串的警告,很不舒服。因?yàn)橛芯?,說(shuō)明代碼可以?xún)?yōu)化,或者有問(wèn)題。幾天前,我在團(tuán)隊(duì)中發(fā)現(xiàn)了一個(gè)小錯(cuò)誤。和我沒(méi)有關(guān)系,只是同事們?cè)谕饷婵礃I(yè)務(wù),判斷業(yè)務(wù)為什么錯(cuò)了。我掃了一眼問(wèn)題。
因?yàn)閖ava中的整型字面量int是類(lèi)型的,所以它們變成Integer了集合,然后點(diǎn)擊它stepId就是一個(gè)long類(lèi)型,而Long在集合中,那么這contains正確返回false了,它不是一個(gè)類(lèi)型。
你看,如果你注意警告,你可以把鼠標(biāo)移到上面看一下提示,就會(huì)少一個(gè)生產(chǎn)bug。
9、盡可能使用新的技術(shù)組件
我認(rèn)為這是一個(gè)程序員應(yīng)該具備的素質(zhì)。反正我喜歡用新的技術(shù)部件,因?yàn)樾录夹g(shù)組件的出現(xiàn)是解決老技術(shù)組件的不足,而作為技術(shù)人員,我們應(yīng)該與時(shí)俱進(jìn)。
當(dāng)然,前提是做好準(zhǔn)備,而不是想當(dāng)然地升級(jí)。Java 17 已經(jīng)發(fā)布了最簡(jiǎn)單的例子,新項(xiàng)目仍然使用Date來(lái)處理 DateTime。