iT邦幫忙

2025 iThome 鐵人賽

DAY 29
0

聯繫我

如果有任何問題或建議,歡迎隨時聯繫我:

前言

在過去的 28 天裡,我們學習了如何建構功能、管理狀態、編寫測試、優化效能。我們已經掌握了「讓功能動起來」的各種技能。

但軟體開發還有另一面,同樣重要,卻常常被忽略:如何讓程式碼在未來依然容易被理解、修改和擴展? 這就是「可維護性 (Maintainability)」。

想像一下你家的廚房。當你為了趕時間,匆匆忙忙地做完一頓飯,可能就把用過的鍋子、盤子隨手一放,心想「等等再來收」。一次兩次還好,但如果每天都這樣,一週後,你的廚房就會變成一個油膩、混亂、讓你完全不想走進去的災難現場。在這樣的廚房裡,即使只是想簡單地下個麵,都會變得很困難。

程式碼也是一樣。在專案初期、在趕死線的壓力下,我們常常會寫一些「能動就好」的程式碼。這些權宜之計,就是「技術債 (Technical Debt)」。債務會累積,利息會增長,最終會讓整個專案的開發速度變得極其緩慢,每一次小小的修改都伴隨著巨大的痛苦和風險。

而「重構 (Refactoring)」,就是定期清理和整理你那混亂廚房的過程。它是一項紀律,是專業開發者對抗混亂、保持程式碼品質的關鍵武器。

1. 什麼是重構?

軟體工程大師 Martin Fowler 給了它一個經典定義:

重構,是在不改變軟體外部行為的前提下,修改其內部結構,以提高其可理解性,並降低其修改成本的過程。

簡單來說,重構就是:

  • 修改功能(Bug 修復和新增功能都不算重構)。
  • 改善程式碼的設計、結構和可讀性。

重構的底氣從何而來? 來自我們前幾天學的「自動化測試」!一個覆蓋率良好的測試套件,就是你進行重構時最大的安全網。它能確保你在大刀闊斧地修改內部結構時,沒有意外破壞任何外部功能。

2. 識別程式碼的「壞味道 (Bad Smells)」

「壞味道」是程式碼中一些顯而易見的警訊,它們暗示著底下可能存在更深層的設計問題。讓我們來看看在 Vue 專案中幾種常見的壞味道,以及如何「除臭」。

味道一:臃腫的元件 (The Bloated Component)

  • 氣味:一個 .vue 檔案超過 500 行,甚至上千行。它像一頭巨獸,掌管著資料獲取、複雜的表單邏輯、多種狀態管理、還有超長的 HTML 模板。
  • 問題:難以理解、難以測試、難以複用。修改其中一小部分,都可能影響到其他看似無關的功能。
  • 重構手法
    1. 提取元件 (Extract Component):將模板中一塊相對獨立的 UI 和相關邏輯,抽離成一個新的子元件。例如,一個複雜的使用者個人資料頁面,可以將「頭像上傳區」、「基本資料表單」、「修改密碼區」分別提取成獨立的子元件。
    2. 提取邏輯 (Extract Composable):將元件中可複用的「非視覺」邏輯(例如:API 請求、事件監聽、資料格式化)抽離成一個 useXXX.js 的 Composable 函式 (我們在 Day 10 學過)。

味道二:Props 逐層傳遞 (Prop Drilling)

  • 氣味:一個 user 物件,從 App.vue -> Layout.vue -> Page.vue -> UserProfile.vue,一層一層地透過 props 往下傳。中間的 LayoutPage 元件本身根本不需要 user,它們只是充當「快遞員」。
  • 問題:讓元件之間產生不必要的耦合,修改資料源時需要追蹤整條傳遞鏈,非常痛苦。
  • 重構手法
    1. 狀態管理 (State Management):如果這個資料是全域共享的(例如登入使用者資訊),那麼它最適合的家就是 Pinia (Day 12)。任何元件都可以直接從 Store 中獲取,無需傳遞。
    2. Provide / Inject:如果資料只在某個元件子樹中共享,可以使用 provide 在祖先元件提供資料,在任何後代元件中用 inject 來注入。這比 props 簡潔,但會讓資料流動變得不那麼明確,需謹慎使用。

味道三:神秘的字串與數字 (Magic Strings & Numbers)

  • 氣味:在程式碼中看到一些不知所云的字面值。
    if (order.status === 3) { /* ... */ }
    const notificationType = 'success';
    element.style.color = '#1976d2';
    
  • 問題:可讀性差(3 是什麼意思?已出貨?已完成?),且難以維護(如果狀態碼要從 3 改成 4,你需要在整個專案中搜索替換)。
  • 重構手法
    1. 提取常數 (Extract Constant):用一個有意義的常數名來取代這些神秘值。
    // src/constants.js
    export const ORDER_STATUS = {
      PENDING: 1,
      PROCESSING: 2,
      SHIPPED: 3,
      DELIVERED: 4,
    };
    
    // 在元件中
    import { ORDER_STATUS } from '@/constants';
    if (order.status === ORDER_STATUS.SHIPPED) { /* ... */ }
    

味道四:重複的邏輯 (Duplicated Logic)

  • 氣味:你在 A 元件寫了一段計算購物車總價的邏輯,後來發現 B 元件也需要,於是你熟練地複製貼上。
  • 問題:違反了 DRY (Don't Repeat Yourself) 原則。當計算邏輯需要修改時(例如要加上稅金),你必須記得到所有複製過的地方去修改,很容易遺漏。
  • 重構手法
    1. 提取工具函式 (Extract Utility Function):如果邏輯是純粹的資料處理(不依賴 Vue 的響應式系統),就把它抽到一個 src/utils 資料夾下的共用函式。
    2. 提取 Composable:如果邏輯和 Vue 的響應式 API 有關(例如,它本身是一個 computed),那麼 Composable 就是它最好的歸宿。

3. 如何開始重構?

  • 遵循童子軍原則:「永遠讓營地比你來時更乾淨」。在你修改一個檔案以新增功能或修復 Bug 時,順手清理一下旁邊你看到的壞味道。積少成多,程式碼品質就會持續提升。
  • 小步前進:不要試圖一次性重構整個應用。一次只針對一個壞味道,完成一個小重構,執行測試,提交。小步快跑,安全可靠。

本篇自我挑戰

  1. 尋找巨獸:打開你的專案,找到那個讓你一看就頭痛的、最龐大的元件。試著分析一下,它的哪些部分可以被提取成更小的子元件或 Composable?
  2. 尋找神秘數字:在你的程式碼中搜索硬編碼的數字或字串(例如 status: 2, type: 'admin')。嘗試將它們提取到一個 constants.js 檔案中,並用有意義的名稱取代它們。
  3. 尋找重複:在你專案的兩個不同檔案中,找一段被複製貼上的程式碼。根據它的性質,將它重構為一個共用的工具函式或 Composable。

總結

今天,我們探討了軟體品質的核心——可維護性。寫出能動的程式碼是基本,寫出能讓半年後的自己和同事都能輕鬆看懂和修改的程式碼,才是一種專業。

  • 重構是保持程式碼健康的紀律性活動,而測試是重構的基石。
  • 我們學會了識別 Vue 中的常見壞味道:臃腫元件、Props 逐層傳遞、神秘值和重複邏輯。
  • 我們也掌握了對應的重構手法:提取元件/邏輯、使用狀態管理、提取常數等。

良好的程式碼結構,就像一個乾淨整潔的廚房,它能讓你享受烹飪(開發)的樂趣,而不是在混亂中掙扎。這也是我們作為專業工程師,寫給未來的自己和團隊的一封最溫柔的信。

明天,我們將迎來這次鐵人賽的最後一天,讓我們一起總結 Vue 的開發最佳實踐,並展望它的未來與生態系。

本日關鍵字回顧

  • 重構 (Refactoring)
  • 可維護性 (Maintainability)
  • 技術債 (Technical Debt)
  • 壞味道 (Bad Smells)
  • 臃腫的元件 (Bloated Component)
  • Props 逐層傳遞 (Prop Drilling)
  • Provide / Inject
  • 神秘的字串/數字 (Magic String/Number)
  • 提取元件 (Extract Component)
  • 提取邏輯 (Extract Composable)

上一篇
【Day 28】縮小你的首屏負擔:Code Splitting 與 Lazy Loading
下一篇
【Day 30】旅程的終點,新世界的起點:Vue 的未來與生態系
系列文
Vue 全攻略:30 天技能樹養成30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言