自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

做了1000次Code Review,我學(xué)到這3點(diǎn)經(jīng)驗(yàn)

新聞 前端
Code Review 是保證代碼質(zhì)量的重要手段。Steven Heidel 曾在 LinkedIn 負(fù)責(zé) Code Review,他在本文總結(jié)了常見(jiàn)的代碼問(wèn)題并提出修改方案。

[[314223]]

 Code Review 是保證代碼質(zhì)量的重要手段。Steven Heidel 曾在 LinkedIn 負(fù)責(zé) Code Review,他在本文總結(jié)了常見(jiàn)的代碼問(wèn)題并提出修改方案。

當(dāng)我在 LinkedIn 工作時(shí),工作的很大一部分內(nèi)容是做 Code Review。在這個(gè)過(guò)程中,我發(fā)現(xiàn)一些人很容易犯的錯(cuò)誤,于是把錯(cuò)誤整理起來(lái)并分享給團(tuán)隊(duì)。

經(jīng)驗(yàn) 1:當(dāng)出現(xiàn)錯(cuò)誤時(shí) Throw an exception

我看到的一個(gè)常見(jiàn)模式是:

  1. List<String> getSearchResults(...) { 
  2.   try { 
  3.     List<String> results = // make REST call to search service 
  4.     return results; 
  5.   } catch (RemoteInvocationException e) { 
  6.     return Collections.emptyList(); 
  7.   } 

上面的方法可能是很多新手工程師的做法,但這種模式會(huì)有問(wèn)題。在我曾經(jīng)參與的移動(dòng)應(yīng)用中,這種模式導(dǎo)致移動(dòng)應(yīng)用程序的故障。用戶(hù)搜索開(kāi)始后,我們的后端發(fā)生錯(cuò)誤開(kāi)始 throwing exceptions,但在應(yīng)用程序的 API server 中并沒(méi)有 throwing exceptions。

因此,從應(yīng)用角度看,前端會(huì)收到 200 個(gè)成功的響應(yīng),然后顯示空白的搜索結(jié)果給使用者,而團(tuán)隊(duì)卻毫不知情。

如果 API  thrown an exception,那我們的監(jiān)控系統(tǒng)會(huì)立刻發(fā)現(xiàn)它,并能及時(shí)修復(fù)。

很多時(shí)候,當(dāng)捕捉到異常后,我們傾向于返回 empty object。Java 中 empty object 的樣例包括 Optional.empty()、null 和 empty list。這種情況經(jīng)常發(fā)生在 URL 解析中。如果 URL 無(wú)法從字符串解析得到的話,不要返回 null,而要問(wèn)問(wèn)自己:

URL 格式為什么是不合法的?這是一個(gè)需要在 upstream 解決的數(shù)據(jù)問(wèn)題嗎?

對(duì)于這種任務(wù)來(lái)說(shuō),empty object 并不是恰當(dāng)?shù)墓ぞ?。如果出現(xiàn)異常行為,那么就應(yīng)該 throw an exception。

經(jīng)驗(yàn) 2:盡可能使用最具體的類(lèi)型(type)

基本而言,這條建議恰好與 stringly typed programming 相反。

我經(jīng)??吹较旅嫠镜拇a:

  1. void doOperation(String opType, Data data);  
  2. // where opType is "insert", "append", or "delete", this should have clearly been an enum 
  3.  
  4. String fetchWebsite(String url); 
  5. // where url is "https://google.com", this should have been an URN 
  6.  
  7. String parseId(Input input); 
  8. // the return type is String but ids are actually Longs like "6345789" 

用最具體的類(lèi)型 (type)可以避免很多 bug。

現(xiàn)在問(wèn)題是:好心的程序員為什么會(huì)寫(xiě)出糟糕的 stringly typed 代碼?

答案在于外部世界不是強(qiáng)類(lèi)型的。字符串有很多不同的來(lái)源,比如:

  • url 中的查詢(xún)和路徑參數(shù)
  • JSON
  • 不支持枚舉的數(shù)據(jù)庫(kù)
  • 編寫(xiě)糟糕的庫(kù)

在上述場(chǎng)景中,我們應(yīng)使用如下的策略來(lái)避免該問(wèn)題:將字符串解析和序列化放在程序的邊緣之處。

下面是這樣一個(gè)樣例:

  1. // Step 1: Take a query param representing a company name / member id pair and parse it 
  2. // example: context=Pair(linkedin,456) 
  3. Pair<String, Long> companyMember = parseQueryParam("context"); 
  4. // this should throw an exception if malformed 
  5.  
  6. // Step 2: Do all the stuff in your application 
  7. // MOST if not all of your code should live in this area 
  8.  
  9. // Step 3: Convert the parameter back into a String at the very end if necessary 
  10. String redirectLink = serializeQueryParam("context"); 

這種方式有很多優(yōu)點(diǎn)。立即發(fā)現(xiàn)格式錯(cuò)誤的數(shù)據(jù);如果出現(xiàn)任何問(wèn)題,應(yīng)用程序?qū)⑻崆?fails。數(shù)據(jù)被驗(yàn)證一次后,不必在整個(gè)應(yīng)用程序中繼續(xù)捕獲解析異常。

此外,強(qiáng)類(lèi)型使方法簽名更具描述性,我們不再需要在每個(gè)方法上編寫(xiě)那么多的 javadocs。

經(jīng)驗(yàn) 3:用 Optionals 而非 nulls

Java 8 帶來(lái)最棒的特性之一是Optional類(lèi),它代表一個(gè)可能存在也可能不存在的實(shí)體。

一個(gè)小問(wèn)題:

唯一擁有自己縮寫(xiě)的例外(exception)是什么?答案是 NPE 或空指針異常。截至目前,它是 Java 中最常見(jiàn)的異常,并被稱(chēng)為價(jià)值 10 億美元的錯(cuò)誤 (https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare )。

Optional能讓我們完全從程序中移除 NPE。但是,必須以正確的方式使用它。如下是關(guān)于使用Optional的一些建議:

  • 我們不能在得到Optional的任何時(shí)候都簡(jiǎn)單地調(diào)用它的.get(),相反,我們要仔細(xì)考慮Optional不存在的情況并給出一個(gè)合理的默認(rèn)值;
  • 如果還沒(méi)有合理的默認(rèn)值,那么像.map()和.flatmap()這樣的方法允許我們推遲到以后再做決定;
  • 如果外部庫(kù)返回null來(lái)表示為空的情況,那么立即使用Optional.ofNullable()wrap 該值。相信我,你以后會(huì)感謝自己的。null 值在程序內(nèi)部有“bubble up”的傾向,所以最好在源代碼中停止它們;
  • 在方法的返回類(lèi)型中使用Optional。這種做法非常好,因?yàn)槲覀儾恍枰x取 javadoc 來(lái)確定值是否可能不存在。

額外建議:盡可能采用“Unlift”方法

我們應(yīng)避免下面所示的方法:

  1. // AVOID: 
  2. CompletableFuture<T> method(CompletableFuture<S> param); 
  3. // PREFER:  
  4. T method(S param); 
  5.  
  6. // AVOID: 
  7. List<T> method(List<S> param); 
  8. // PREFER: 
  9. T method(S param); 
  10.  
  11. // AVOID:  
  12. T method(A param1, B param2, Optional<C> param3); 
  13. // PREFER: 
  14. T method(A param1, B param2, C param3); 
  15. T method(A param1, B param2); 
  16. // This method is clearly doing two things, it should be two methods 
  17. // The same is true for boolean parameters 

上述不推薦使用的方法有哪些共同點(diǎn)?那就是它們都使用了 container objects 作為參數(shù),比如 Optional、List 或 Task。

如果返回類(lèi)型是相同種類(lèi)的 container,那就更糟糕了(比如,param methods 接收 Optional,返回值也是 Optional)。

為什么呢?

1)Promise<A> method(Promise<B> param)要比 2)A method(B param)更缺少靈活性。

如果有一個(gè)Promise<B>的話,我們可以用 1),也能通過(guò).map函數(shù)使用 2)(即promise.map(method))。

但是,如果只有一個(gè) B 的話,我們很容易使用 2),但是無(wú)法使用 1),這樣來(lái)看,2) 是更具靈活性的方案。

我喜歡將其稱(chēng)為“unlifting”,因?yàn)樗c常見(jiàn)的函數(shù)式工具方法“lift”恰好相反。采用這種方式重寫(xiě)會(huì)讓方法更具靈活性,對(duì)調(diào)用者更加易用。

 

責(zé)任編輯:張燕妮 來(lái)源: 架構(gòu)頭條
相關(guān)推薦

2021-04-27 10:02:40

股票數(shù)組代碼

2020-12-25 09:38:07

Vue前端代碼

2018-08-16 15:11:47

Code ReviewPPT代碼

2020-05-19 13:46:33

勒索軟件信息安全攻擊

2015-11-17 16:11:07

Code Review

2022-10-27 10:33:48

敏捷開(kāi)發(fā)開(kāi)發(fā)

2018-05-25 17:10:20

谷歌溝通經(jīng)驗(yàn)

2012-07-05 09:45:02

代碼審查

2013-10-24 09:43:58

代碼代碼審查

2010-12-02 11:01:23

職場(chǎng)經(jīng)驗(yàn)

2021-08-09 06:57:41

CodeReview流程

2019-02-28 09:53:21

IT互聯(lián)網(wǎng)職場(chǎng)

2021-04-25 09:19:22

騰訊Code Reviewleader

2009-08-05 09:59:40

Code Review代碼審查工具

2024-11-08 14:18:38

2020-05-27 11:25:48

開(kāi)發(fā)技能代碼

2014-04-15 13:16:00

Code Review

2022-06-23 09:57:01

code-revie前端代碼

2017-07-20 13:11:46

Code ReviewPR評(píng)審

2012-09-03 13:41:50

Code Review
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)