🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

我用AI重構了一段500行的屎山程式碼,這是我的Prompt和思考過程

image.png

大家好,我來了🙂。

我們團隊,維護著一個有5年歷史的史詩級中後台專案😖。在這座屎山裡,有一個叫handleOrderSubmit.js的檔案。

可以下載瞧一瞧 有多屎👉 handleOrderSubmit.js

它是一個長達500多行的React useEffect 鉤子函數(是的,你沒看錯,一個useEffect)。

它混合了訂單資料的本地校驗價格計算優惠券應用API請求全域狀態更新、以及錯誤彈窗處理... 所有的邏輯,都塞在一個函數裡,用if/elsetry/catch層層嵌套。

沒人敢動它😖。

本事試試看.gif

每次產品經理提一個小需求,比如在提交訂單時,增加一種新的優惠券類型,我們整個團隊的表情都像被雷劈了。因為我們知道,改這個函數,要麼加班一週,要麼就等著P0級事故。

上週,產品經理要求我們在這個函數裡,加入一個全新的風控邏輯。

我評估了一下,手動重構,至少需要一個資深工程師一週的時間,而且風險極大。

我受夠了。我決定,把這個燙手的任務,扔給我的實習生——AI(我用的是GPT-5 mini,窮😂)。

這篇文章,就是我人機協作,啃下這塊硬骨頭的完整回顧,大家繼續看。


我不能直接說重構它

我犯的第一個錯誤,是直接把500行程式碼貼給AI,然後說:幫我重構這段程式碼

AI很聽話,它給我的,是一段看起來更整潔的程式碼——它把if/else換成了switch,提了幾個變數... 這不叫重構,這叫重新排版,毫無意義。

我很快意識到:AI是一個能力超強、但沒有靈魂的執行者。我,作為開發者,必須給它提供一個清晰的方案。

於是,我制定了一個五步重構法


我的Prompt和思考

我的核心思想是:AI負責執行,我負責決策。 我要像一個指揮家一樣,一步一步地引導AI,把這500行的程式碼,拆解成高內聚、低耦合的模組。

第一步:先讓AI讀懂屎山

我不能上來就讓AI改。我得先確認,它和我對這段程式碼的理解,在一個頻道上。

Prompt:

你是一個資深的React架構師。請分析下面這段500行的useEffect程式碼。

  1. 告訴我它做了幾件主要的事情?(職責分析)
  2. 找出所有的副作用(比如API請求、localStorage操作、全域狀態更新)。
  3. 找出所有的純邏輯(比如資料校驗、價格計算)。
  4. 評價它的可維護性和可測試性

image.png

GPT的回答,給了我一個驚喜。它清晰地列出了:

  1. 職責:它承擔了至少5個職責:表單校驗、價格計算、庫存檢查、創建訂單、處理UI反饋。
  2. 副作用api.post(...), setLoading(true), showToast(...)...
  3. 純邏輯validateForm(...), calculateTotalPrice(...)...
  4. 評價:可維護性極低,單一職責原則被嚴重違反,幾乎不可測試。

很好,AI看懂了!我們就可以開始了😁。

第二步:先分離純邏輯程式碼

這是最關鍵的一步。我要把計算和動作分開。

Prompt:

非常好。現在,請你只針對純邏輯部分(表單校驗、價格計算)進行重構。

  1. 把這些邏輯,從原函數中提取出來,變成獨立的、可導出的純函數
  2. 這些函數必須是純的:不能有任何副作用(不能調用apisetLoading)。
  3. 使用TypeScript,為這些新函數的入參和返回值,提供清晰的類型定義。

image.png

AI立刻唰唰唰地給了我幾個檔案:

validate.ts:

export function validateOrder(formData: OrderForm): string | null {
  if (!formData.user) return '用戶信息不能為空';
  if (formData.items.length === 0) return '商品不能為空';
  // ... 10 more rules
  return null;
}

calculator.ts:

export function calculateTotalPrice(items: Item[], coupon: Coupon): number {
  let total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
  if (coupon.type === 'PERCENT') {
    total *= (1 - coupon.value / 100);
  }
  // ... 20 more rules
  return total;
}
第三步:讓AI為自己的程式碼做測試

我怎麼知道AI提煉的邏輯,是對的還是錯的?
答案:讓它自己寫單元測試來證明。

Prompt:

你現在是一個QA工程師。請使用Vitest,為你剛才提取的validateOrdercalculateTotalPrice這兩個函數,編寫全面的單元測試用例
必須覆蓋所有邊界情況,包括正常、異常、和邊緣值。

AI再次給了我驚喜。它生成的測試用例,比我手寫的還要全:

// calculator.test.ts
import { describe, it, expect } from 'vitest';
import { calculateTotalPrice } from './calculator';

describe('calculateTotalPrice', () => {
  it('should return 0 for empty cart', () => {
    expect(calculateTotalPrice([], null)).toBe(0);
  });

  it('should apply percent coupon', () => {
    const items = [{ price: 100, quantity: 1 }];
    const coupon = { type: 'PERCENT', value: 10 };
    expect(calculateTotalPrice(items, coupon)).toBe(90);
  });
  // ... 省略更多
});

我把這些測試用例跑了一遍,全部通過。我現在信心大增😁。

第四步:重寫協調層

現在,純邏輯已經被分離並驗證了。原來的500行屎山,只剩下副作用和流程控制程式碼了。是時候重寫它了。

Prompt:

幹得漂亮。現在,我們來重構那個原始的useEffect函數

  1. 它現在唯一的職責是協調
  2. 調用我們剛才創建的validateOrdercalculateTotalPrice純函數。
  3. 把所有的副作用(API請求、setLoadingshowToast清晰地編排起來。
  4. 使用async/await,讓異步流程更清晰,用try/catch處理錯誤。

這次,AI給我的,是一個只有30行左右的、清晰的流程程式碼:

// 重構後的 useEffect
useEffect(() => {
  const submitOrder = async () => {
    setLoading(true);
    try {
      // 1. 協調:驗證 (純)
      const errorMsg = validateOrder(formData);
      if (errorMsg) {
        showToast(errorMsg);
        return;
      }

      // 2. 協調:計算 (純)
      const totalPrice = calculateTotalPrice(formData.items, formData.coupon);

      // 3. 協調:副作用(不純)
      const result = await api.post('/order/submit', { ...formData, totalPrice });

      // 4. 協調:響應(不純)
      if (result.code === 200) {
        showToast('訂單提交成功!');
        router.push('/success');
      } else {
        showToast(result.message);
      }
    } catch (err) {
      showToast(err.message);
    } finally {
      setLoading(false);
    }
  };

  if (isSubmitting) { // 假設一個觸發條件
    submitOrder();
    setIsSubmitting(false);
  }
}, [isSubmitting, formData /* ...其他依賴 */]);
第五步:最後守衛工作,加入新功能

別忘了,我重構的目的,是為了加風控這個新功能。

Prompt:

最一步。請在API請求之前,加入一個風控檢查的邏輯(調用riskControl.check(...))。這是一個異步函數,如果檢查不通過,它會拋出一個錯誤。

AI在第2步和第3步之間,加了幾行程式碼,完美收工。


這次重構,我總共花了大概5個小時,而不是原計劃的一週。

總覺得 AI 不會淘汰會寫程式碼的工程師。

只會降維打擊那些只會堆砌程式碼的工程師。

那段500行的屎山,在過去,是我的噩夢;現在,有了AI的幫助,它變成了我的靶場。

這種感覺,真爽🙌。


原文出處:https://juejin.cn/post/7570630923710054452


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝13   💬4   ❤️4
438
🥈
我愛JS
📝1   💬3   ❤️2
46
🥉
酷豪
1
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付