偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

擺脫 if-else 束縛的清潔編碼之旅:這些技術(shù)幫你實現(xiàn)

開發(fā) 前端
面條代碼往往出現(xiàn)在無腦的“粗暴、快速、猛烈”風格的開發(fā)中。許多 bug 修復是通過粗暴地在這里添加一個 if 并在多處返回語句來完成的,再加上缺乏注釋,這很容易導致代碼可讀性降低和復雜性增加。

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

什么是意大利面條代碼?

所謂“意大利面條代碼”在處理復雜業(yè)務過程時很常見。它通常具有以下特點:

  • 內(nèi)容冗長
  • 結(jié)構(gòu)混亂
  • 嵌套深

我們知道,主流編程語言都有函數(shù)或方法來組織代碼。對于意大利面條代碼,我們可以將其視為滿足這些特點的函數(shù)。根據(jù)語言語義的不同,可以將其分為兩種基本類型:

if…if 類型

這種代碼結(jié)構(gòu)看起來像這樣:

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)) {
    // ...
  }
}

其流程圖如下:

圖片圖片

通過自上而下嵌套 if 語句,單個函數(shù)內(nèi)的控制流不斷增長。不要以為控制流增長時,復雜性只是線性增加。我們知道,函數(shù)處理數(shù)據(jù),每個 if 內(nèi)通常都有數(shù)據(jù)處理邏輯。所以即使沒有嵌套,如果有 3 個這樣的 if 段,那么根據(jù)每個 if 是否執(zhí)行,會有 2 ^ 3 = 8 種可能的數(shù)據(jù)狀態(tài)。如果有 6 段,則會有 2 ^ 6 = 64 種狀態(tài)。因此,隨著項目規(guī)模的擴大,調(diào)試函數(shù)變得指數(shù)級困難!在數(shù)量級上,這與《人月神話》中分享的經(jīng)驗一致。

else if…else if 類型

這種代碼控制流也很常見,看起來像這樣:

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)) {
    // ...
  }
}

其流程圖如下:

圖片圖片

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

但為什么在框架和庫如此先進的時代,我們?nèi)匀唤?jīng)常遇到這樣的代碼?在我看來,可復用的模塊確實幫助我們減少了模板代碼;然而,不管業(yè)務邏輯封裝得多好,開發(fā)者仍需要編寫它。即使是簡單的 if-else 語句,也能成倍增加控制流的復雜性。從這個角度看,如果沒有基本的編程技巧,不管多快掌握優(yōu)秀的框架和庫,你可能仍然會寫出混亂的項目。

重構(gòu)策略

在上文中,我們討論了兩種面條代碼,并定量展示了它們?nèi)绾纬杀对黾涌刂屏鞯膹碗s性。然而,在現(xiàn)代編程語言中,這種復雜性實際上是完全可控的。以下是列舉的幾種編程技巧來改善面條代碼的場景。

圖片圖片

基本情況

對于 if…if 類型的面條代碼,可以通過基本函數(shù)拆分來解決復雜性增長的問題。下圖中每個綠色框代表一個拆分出的新函數(shù):

由于現(xiàn)代編程語言中放棄了 goto,無論控制流多復雜,函數(shù)體內(nèi)代碼的執(zhí)行順序總是自上而下的。因此,我們完全可以從上到下逐步將單體大函數(shù)拆分為多個小函數(shù)而不改變控制流邏輯,然后一個個調(diào)用它們。這是經(jīng)驗豐富的同事常用的技巧,具體代碼實現(xiàn)這里不再詳細闡述。

需要注意的是,這種方法中所謂的不改變控制流邏輯是指不需要改變業(yè)務邏輯執(zhí)行的方式,只是將代碼移出去并包裹一層函數(shù)。有些同學可能認為這種方法只是治標不治本——它只是將一段長面條切成幾段短面條,沒有本質(zhì)區(qū)別。

但真的是這樣嗎?通過這種方法,我們可以將具有 64 種狀態(tài)的大函數(shù)拆分為 6 個只返回 2 種狀態(tài)的小函數(shù),以及一個逐一調(diào)用它們的主函數(shù)。這樣,每個函數(shù)的復雜性增長率從指數(shù)級降低為線性。

通過這種方式,我們解決了 if…if 類型的面條代碼;那么else if…else if類型的呢?

查找表

對于 “else if…else if” 類型的面條代碼,一種最簡單的重構(gòu)策略是使用所謂的查找表。它以鍵值對的形式封裝每個 else if 中的邏輯:

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 中的邏輯被重寫為一個獨立的函數(shù),然后我們可以按以下方式拆分過程:

圖片圖片

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

責任鏈模式

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

對于 else if,需要注意每個分支是自上而下判斷的,最終只會執(zhí)行其中一個。這意味著我們可以通過存儲一個“判斷規(guī)則”的數(shù)組來實現(xiàn)這種行為。如果一個規(guī)則匹配,則執(zhí)行該規(guī)則對應的分支。我們稱這樣的數(shù)組為“責任鏈”,其模式下的執(zhí)行過程如圖所示:

圖片圖片

在代碼實現(xiàn)中,我們可以通過責任鏈數(shù)組定義等價于else if的規(guī)則。

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 函數(shù)重寫為遍歷責任鏈數(shù)組:

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)
    }
  }
}

當每個責任被匹配時,原函數(shù)將直接返回,這也完全符合 else if 的語義。這樣,我們實現(xiàn)了將復雜的 else if 邏輯拆分為單獨的部分。

結(jié)尾

面條代碼往往出現(xiàn)在無腦的“粗暴、快速、猛烈”風格的開發(fā)中。許多 bug 修復是通過粗暴地在這里添加一個 if 并在多處返回語句來完成的,再加上缺乏注釋,這很容易導致代碼可讀性降低和復雜性增加。

然而,解決這個問題其實并不復雜。這些示例之所以簡單,基本上是因為強大的高級編程

責任編輯:武曉燕 來源: 大遷世界
相關(guān)推薦

2012-12-07 13:22:49

辦公打印

2023-06-02 07:30:24

If-else結(jié)構(gòu)流程控制

2013-03-06 10:28:57

ifJava

2010-11-08 14:01:05

私有云

2021-03-10 07:20:43

if-else靜態(tài)代碼

2021-04-13 06:39:13

代碼重構(gòu)code

2013-09-24 14:43:55

Windows Sky云存儲

2021-11-04 08:53:00

if-else代碼Java

2022-07-11 08:16:55

策略模式if-else

2020-10-22 09:20:22

SQLNoSQL 數(shù)據(jù)庫

2020-04-09 08:29:50

編程語言事件驅(qū)動

2010-08-11 09:37:33

無線路由故障

2014-04-24 10:37:25

動態(tài)管理云計算

2010-04-02 16:05:55

無線路由器

2025-04-24 08:40:00

JavaScript代碼return語句

2020-12-15 09:31:58

CTOif-else代碼

2020-05-13 14:15:25

if-else代碼前端

2014-09-05 11:15:00

移動辦公移動云

2021-03-01 08:55:23

物聯(lián)網(wǎng)清潔技術(shù)IOT

2020-09-27 14:24:58

if-else cod業(yè)務
點贊
收藏

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