日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

擺脫 if-else 束縛的清潔編碼之旅:這些技術幫你實現

來源: 責編: 時間:2024-07-06 07:44:59 936觀看
導讀許多學生在維護舊項目時遇到過復雜的業務邏輯嵌套在深層的if-else語句中。面對這樣的亂象,簡單地增量修改通常只會增加復雜性和降低可讀性。那么,有沒有固定的套路可以整理這些代碼呢?這里分享三種簡單而常見的重構方法

許多學生在維護舊項目時遇到過復雜的業務邏輯嵌套在深層的if-else語句中。面對這樣的亂象,簡單地增量修改通常只會增加復雜性和降低可讀性。那么,有沒有固定的套路可以整理這些代碼呢?這里分享三種簡單而常見的重構方法。HHa28資訊網——每日最新資訊28at.com

什么是意大利面條代碼?

所謂“意大利面條代碼”在處理復雜業務過程時很常見。它通常具有以下特點:HHa28資訊網——每日最新資訊28at.com

  • 內容冗長
  • 結構混亂
  • 嵌套深

我們知道,主流編程語言都有函數或方法來組織代碼。對于意大利面條代碼,我們可以將其視為滿足這些特點的函數。根據語言語義的不同,可以將其分為兩種基本類型:HHa28資訊網——每日最新資訊28at.com

if…if 類型

這種代碼結構看起來像這樣:HHa28資訊網——每日最新資訊28at.com

function demo(a, b, c) {  if (f(a, b, c)) {    if (g(a, b, c)) {      // ...    }    // ...    if (h(a, b, c)) {      // ...    }  }  if (j(a, b, c)) {    // ...  }  if (k(a, b, c)) {    // ...  }}

其流程圖如下:HHa28資訊網——每日最新資訊28at.com

圖片圖片HHa28資訊網——每日最新資訊28at.com

通過自上而下嵌套 if 語句,單個函數內的控制流不斷增長。不要以為控制流增長時,復雜性只是線性增加。我們知道,函數處理數據,每個 if 內通常都有數據處理邏輯。所以即使沒有嵌套,如果有 3 個這樣的 if 段,那么根據每個 if 是否執行,會有 2 ^ 3 = 8 種可能的數據狀態。如果有 6 段,則會有 2 ^ 6 = 64 種狀態。因此,隨著項目規模的擴大,調試函數變得指數級困難!在數量級上,這與《人月神話》中分享的經驗一致。HHa28資訊網——每日最新資訊28at.com

else if…else if 類型

這種代碼控制流也很常見,看起來像這樣:HHa28資訊網——每日最新資訊28at.com

function demo(a, b, c) {  if (f(a, b, c)) {    if (g(a, b, c)) {      // ...    } else if (h(a, b, c)) {      // ...    }    // ...  } else if (j(a, b, c)) {    // ...  } else if (k(a, b, c)) {    // ...  }}

其流程圖如下:HHa28資訊網——每日最新資訊28at.com

圖片圖片HHa28資訊網——每日最新資訊28at.com

else if 最終只會進入其中一個分支,因此不會像前面提到的那樣出現組合爆炸。然而,在深層嵌套中,復雜性依然很高。假設每層嵌套有 3 個 else if 語句,有 3 層嵌套,則會有 3 ^ 3 = 27 種可能的出口。如果每個出口對應一種處理數據的方式,那么在一個函數內封裝這么多邏輯違背了單一職責原則。而且,這兩種類型可以無縫結合,進一步增加復雜性和降低可讀性。HHa28資訊網——每日最新資訊28at.com

但為什么在框架和庫如此先進的時代,我們仍然經常遇到這樣的代碼?在我看來,可復用的模塊確實幫助我們減少了模板代碼;然而,不管業務邏輯封裝得多好,開發者仍需要編寫它。即使是簡單的 if-else 語句,也能成倍增加控制流的復雜性。從這個角度看,如果沒有基本的編程技巧,不管多快掌握優秀的框架和庫,你可能仍然會寫出混亂的項目。HHa28資訊網——每日最新資訊28at.com

重構策略

在上文中,我們討論了兩種面條代碼,并定量展示了它們如何成倍增加控制流的復雜性。然而,在現代編程語言中,這種復雜性實際上是完全可控的。以下是列舉的幾種編程技巧來改善面條代碼的場景。HHa28資訊網——每日最新資訊28at.com

圖片圖片HHa28資訊網——每日最新資訊28at.com

基本情況HHa28資訊網——每日最新資訊28at.com

對于 if…if 類型的面條代碼,可以通過基本函數拆分來解決復雜性增長的問題。下圖中每個綠色框代表一個拆分出的新函數:HHa28資訊網——每日最新資訊28at.com

由于現代編程語言中放棄了 goto,無論控制流多復雜,函數體內代碼的執行順序總是自上而下的。因此,我們完全可以從上到下逐步將單體大函數拆分為多個小函數而不改變控制流邏輯,然后一個個調用它們。這是經驗豐富的同事常用的技巧,具體代碼實現這里不再詳細闡述。HHa28資訊網——每日最新資訊28at.com

需要注意的是,這種方法中所謂的不改變控制流邏輯是指不需要改變業務邏輯執行的方式,只是將代碼移出去并包裹一層函數。有些同學可能認為這種方法只是治標不治本——它只是將一段長面條切成幾段短面條,沒有本質區別。HHa28資訊網——每日最新資訊28at.com

但真的是這樣嗎?通過這種方法,我們可以將具有 64 種狀態的大函數拆分為 6 個只返回 2 種狀態的小函數,以及一個逐一調用它們的主函數。這樣,每個函數的復雜性增長率從指數級降低為線性。HHa28資訊網——每日最新資訊28at.com

通過這種方式,我們解決了 if…if 類型的面條代碼;那么else if…else if類型的呢?HHa28資訊網——每日最新資訊28at.com

查找表

對于 “else if…else if” 類型的面條代碼,一種最簡單的重構策略是使用所謂的查找表。它以鍵值對的形式封裝每個 else if 中的邏輯:HHa28資訊網——每日最新資訊28at.com

const rules = {  x: function (a, b, c) { /* ... */ },  y: function (a, b, c) { /* ... */ },  z: function (a, b, c) { /* ... */ }};function demo(a, b, c) {  const action = determineAction(a, b, c);  return rules[action](a, b, c);}

每個 else if 中的邏輯被重寫為一個獨立的函數,然后我們可以按以下方式拆分過程:HHa28資訊網——每日最新資訊28at.com

圖片圖片HHa28資訊網——每日最新資訊28at.com

對于本身支持反射的腳本語言來說,這是一個相對簡單的技巧。然而,對于更復雜的 else if 條件,這種方法會將控制流復雜性重新集中到 determineAction 中,確定該走哪個分支。有沒有更好的方法來處理這個問題呢?HHa28資訊網——每日最新資訊28at.com

責任鏈模式

在上文中,查找表是通過鍵值對實現的。當每個分支是一個簡單判斷時,如 else if (x === ‘foo’),foo 可以作為重構集合的鍵。然而,如果每個 else if 分支包含復雜的條件判斷并且需要特定的執行順序,我們可以使用責任鏈模式來更好地重構這種邏輯。HHa28資訊網——每日最新資訊28at.com

對于 else if,需要注意每個分支是自上而下判斷的,最終只會執行其中一個。這意味著我們可以通過存儲一個“判斷規則”的數組來實現這種行為。如果一個規則匹配,則執行該規則對應的分支。我們稱這樣的數組為“責任鏈”,其模式下的執行過程如圖所示:HHa28資訊網——每日最新資訊28at.com

圖片圖片HHa28資訊網——每日最新資訊28at.com

HHa28資訊網——每日最新資訊28at.com

在代碼實現中,我們可以通過責任鏈數組定義等價于else if的規則。HHa28資訊網——每日最新資訊28at.com

const rules = [  {    match: function (a, b, c) { /* ... */ },    action: function (a, b, c) { /* ... */ }  },  {    match: function (a, b, c) { /* ... */ },    action: function (a, b, c) { /* ... */ }  },  {    match: function (a, b, c) { /* ... */ },    action: function (a, b, c) { /* ... */ }  }  // ...]

rules 中的每項都具有 match 和 action 屬性。此時我們可以將原來的 else if 函數重寫為遍歷責任鏈數組:HHa28資訊網——每日最新資訊28at.com

function demo (a, b, c) {  for (let i = 0; i < rules.length; i++) {    if (rules[i].match(a, b, c)) {      return rules[i].action(a, b, c)    }  }}

當每個責任被匹配時,原函數將直接返回,這也完全符合 else if 的語義。這樣,我們實現了將復雜的 else if 邏輯拆分為單獨的部分。HHa28資訊網——每日最新資訊28at.com

結尾

面條代碼往往出現在無腦的“粗暴、快速、猛烈”風格的開發中。許多 bug 修復是通過粗暴地在這里添加一個 if 并在多處返回語句來完成的,再加上缺乏注釋,這很容易導致代碼可讀性降低和復雜性增加。HHa28資訊網——每日最新資訊28at.com

然而,解決這個問題其實并不復雜。這些示例之所以簡單,基本上是因為強大的高級編程HHa28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-99171-0.html擺脫 if-else 束縛的清潔編碼之旅:這些技術幫你實現

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 為什么要限流?及常用的限流算法解析

下一篇: 你合并代碼用 Merge 還是用 Rebase ?

標簽:
  • 熱門焦點
  • 6月安卓手機好評榜:魅族20 Pro蟬聯冠軍

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數據來源安兔兔評測,收集時間2023年6月1日至6月30日,僅限國內市場。第一名:魅族20 Pro好評率:95%5月份的時候魅族20 Pro就是
  • 5月iOS設備性能榜:M1 M2依舊是榜單前五

    和上個月一樣,沒有新品發布的iOS設備性能榜的上榜設備并沒有什么更替,僅僅只有跑分變化而產生的排名變動,剛剛開始的蘋果WWDC2023,推出的產品也依舊是新款Mac Pro、新款Mac Stu
  • 使用LLM插件從命令行訪問Llama 2

    最近的一個大新聞是Meta AI推出了新的開源授權的大型語言模型Llama 2。這是一項非常重要的進展:Llama 2可免費用于研究和商業用途。(幾小時前,swyy發現它已從LLaMA 2更名為Lla
  • 當家的盒馬,加速謀生

    來源 | 價值星球Planet作者 | 歸去來自己&ldquo;當家&rdquo;的盒馬,開始加速謀生了。據盒馬官微消息,盒馬計劃今年開放生鮮供應鏈,將其生鮮商品送往食堂。目前,盒馬在上海已經與
  • 微博大門常打開,迎接海外畫師漂洋東渡

    作者:互聯網那些事&ldquo;起猛了,我能看得懂日語了&rdquo;。&ldquo;為什么日本人說話我能聽懂?&rdquo;&ldquo;中文不像中文,日語不像日語,但是我竟然看懂了&rdquo;&hellip;&hell
  • 小米MIX Fold 3下月亮相:今年唯一無短板的全能折疊屏

    這段時間以來,包括三星、一加、榮耀等等有不少品牌旗下的最新折疊屏旗艦都有新的進展,其中榮耀、三星都已陸續發布了最新的折疊屏旗艦,尤其號榮耀Magi
  • 首發天璣9200+ iQOO Neo8系列發布首銷售價2299元起

    2023年5月23日晚,iQOO Neo8系列正式發布。其中,Neo系列首款Pro之作——iQOO Neo8 Pro強悍登場,限時售價3099元起;價位段最強性能手機iQOO Neo8同期上市
  • iQOO Neo8 Pro搶先上架:首發天璣9200+ 安卓性能之王

    經過了一段時間的密集爆料,昨日iQOO官方如期對外宣布:將于5月23日推出全新的iQOO Neo8系列新品,官方稱這是一款擁有旗艦級性能調校的作品。隨著發布時
  • 英特爾Xe HPG游戲顯卡:擁有512EU,單風扇版本

    據10 月 30 日外媒 TheVerge 消息報道,英特爾 Xe HPG Arc Alchemist 的正面實被曝光,不僅擁有 512 EU 版顯卡,還擁有 128EU 的單風扇版本。另外,這款顯卡 PCB
Top 主站蜘蛛池模板: 泸溪县| 玛曲县| 龙川县| 凌海市| 镇远县| 苏尼特左旗| 抚顺市| 务川| 花莲县| 那曲县| 蓬溪县| 缙云县| 广南县| 铜山县| 道孚县| 大余县| 永靖县| 安图县| 尼勒克县| 云阳县| 漠河县| 永川市| 岚皋县| 娄烦县| 双峰县| 桃园县| 仪陇县| 青海省| 宁南县| 宜阳县| 诏安县| 桓台县| 莒南县| 通许县| 安福县| 瑞丽市| 临武县| 日照市| 平凉市| 丹江口市| 东港市|