嗨~ 歡迎閱讀 ExplainThis 全端開發雙週報。這期的主題是《如何優雅地避免程式碼巢狀》。先前在 YouTube 被推薦一個名叫《如何優雅地避免程式碼巢狀》的影片 (連結)。好奇之下點開來看,發現是個品質很高的解說影片。這期雙週報摘要了該影片的重點,與讀者一起來學習如何寫出更優雅的程式碼。
避免巢狀程式碼,僅是寫出乾淨程式的一種方法。除了這個方法,還有很多其他推薦的。上個月 E+ 剛結束《如何寫出乾淨好維護的程式碼》直播工作坊中,談了很多上實務上可以用的方法。
另外,上週 E+ 也剛結束大獲好評的《海外求職與英文面試實戰》直播工作坊,如果對海外求職、練習英文面試等主題感興趣,歡迎加入E+ 觀看直播回放 (E+ 的介紹看這邊)。
[程式設計] - 如何優雅地避免程式碼巢狀
《如何優雅地避免程式碼巢狀》影片一開頭就引用 Linux Kernel 的程式風格指南,由程式界的傳奇 Linus Torvalds 寫下的「如果你的程式碼已經寫到第三層的縮排,那表示程式碼已經開始混亂,要進行修正 If you need more than 3 levels of indentation, you're screwed anyway, and should fix your program」。
要如何避免這種多層的巢狀程式碼呢? 該影片提到了幾種方式,這期我們挑了其中的三個摘要,剩下的推薦大家直接看該影片來了解。
第一種方式,是與其寫下面這種充滿 switch...case
的查找,不如直接用 Map 設計成可以直接查找,可以看到第二種寫法確實比較簡潔,能一眼看懂
// 與其這樣
function choose(subtitle: string): void {
switch (subtitle) {
case "表驅動法":
return "00:16";
case "提早返回":
return "00:39";
}
}
// 不如改成一個 Map,直接查找
const subtitleMap = new Map([
["表驅動法", "00:16"],
["提早返回", "00:39"],
]);
第二種方式,是透過提早回傳,來讓程式碼變好讀一些。影片中的例子是
// 這樣寫 if 中有 if,讀起來會很亂
function getMonthDays(year: number, month:number): number {
if (Number.isIntegre(month) && month <= 12 && month >= 1) {
if (Number.isInteger(year) && year > 0) {
let isLeapYear = // 解說為由,這邊邏輯省略
return monthDays[isLeapYear][month - 1]
} else {
throw new Error("The parameter 'year' is invalid.")
}
} else {
throw new Error("The parameter 'month' is invalid.")
}
}
// 提早回傳可以避免這狀況,會變好讀很多
function getMonthDays(year: number, month:number): number {
if (!Number.isIntegre(month) || month > 12 || month < 1) {
throw new Error("The parameter 'year' is invalid.")
}
if (!Number.isInteger(year) || year < 0) {
throw new Error("The parameter 'year' is invalid.")
}
let isLeapYear = // 解說為由,這邊邏輯省略
return monthDays[isLeapYear][month - 1]
}
第三種是用高階函式 (higher-order function),這基本上是講透過函式編程 (functional programming) 來把程式碼變得更簡潔。舉例來說同樣是過濾,用函式邊程就可以避免多層巢狀
// 要做過濾,可以這樣寫,但是會很多層
let result = Array<JobPosition>();
for (let position of positions) {
if (position.name.includes("Software")) {
result.push(position)
}
}
// 如果用函式邊程,直接用 filter 來過濾,就會更簡潔
let result = positions.filter(position => position.name.includes("Software"))
透過以上三個例子,相信大家能更掌握如何避免寫出多層巢狀程式碼的要訣。該影片還有提到其他的方法,推薦大家可以直接去看,這邊再次附上連結~
[本期推薦]
最近 Builder 的 Steve 發了一個《Good refactoring vs bad refactoring》的影片談重構,非常精闢。重構前真的要妥善評估,不然很可能越改越糟糕 (連結)
用 Rust 寫的 JavaScript 打包工具 Rspack 正式推出 1.0 版本,與 Webpack 高度相容,同時速度比 Webpack 快超過十倍,目前 Amazon、Microsoft 等公司都已經導入 (連結)
如果你是有在開發套件的人,文件化對於使用套件的人來說會很有幫助。先前 Deno 團隊分享了一篇《How to document your JavaScript package》,談了可以如何文件化套件 (連結)
大規模專案遷移是很不容易的事,先前 Coinbase 團隊的 Nick Cherry 分享了將專案遷移到 React Native 過程中的學習 (連結);Malt 團隊先前也分享了將專案遷移到 Nuxt 的心得 (連結)
近年來 JavaScript 的單元測試工具,逐漸從 Jest 轉由 Vitest 成為多數團隊首選。近期有另一個開源專案 Poku,號稱性能比 Vitest 還好,且有更簡單的使用的 API,或許值得持續觀望 (連結)
身為軟體工程師,有時候在衝刺職涯時會忘了休息,但是休息反而是對職涯發展來說,至關重要的元素。先前看到史丹佛大學的短講,談到去最佳化人生 (de-optimize your life),由科學的角度談適時放空的幫助,推薦一看 (連結)
先前聽 Meta 前主任工程師 Evan King 分享,他說在面試中會讓他給 Strong Hire 的候選人,通常是能在面試過程中,讓他覺得有學習的人。這意味著,面試時如果能夠讓面試官覺得你說的內容充滿洞見,對於要過關會很有幫助 (連結)