不要以為一個「模型」或「工具」會永遠都能用。(例如:claude 掛掉集體崩潰現場)
厲害的程式設計師,會想辦法讓程式不要被「某一個小細節」綁死。
就像插座一樣,插頭壞了可以換,電還是能用。
SOLID 五個小規則進度條,最後來到 D。
D — 依賴反轉原則 (Dependency Inversion) 👈 現在在這裡 👈
換句話說:
程式不要只綁定在某個 AI 模型或資料庫上。
要先做一個「規格」(像插座一樣),然後不同零件都可以照這個規格來用。
假設你要做一個「算數學題目」的系統。
錯誤示範(沒有用 DIP):
只能叫 AI 模型算數學。如果 AI 壞掉或太貴,整個系統就掛了。
正確示範(用了 DIP):
先定義一個 MathSolver 規則:
solve(expression: string): number
然後誰都可以照這個規格來解:
AI 模型(叫 AI 算)
自己寫程式(1+1=2)
叫同學幫忙算
這樣系統只依賴「規格」,不用管背後是誰算的。
你想做一個「英文翻中文」的 APP。
const result = openAiTranslate("Hello");
結果:程式只能用 OpenAI 翻譯。
interface Translator {
translate(text: string, to: string): string;
}
然後可以有很多翻譯器:
OpenAI 翻譯(GPT)
Google 翻譯
離線小字典
APP 只依賴「Translator 規格」,不用管背後是哪一個翻譯器。
在真的切換不同 AI 模型以前,我想先做登入功能。
要先有「登入」的功能,確定使用的人有使用的權限。
在開發程式中,我也試著切換不同模型開發,看看會不會有差異。
GPT-5 mini 不像 Claude Sonnet 4 做得那麼完整,
但方向差不多的。Claude Sonnet 4 比較常自己檢查是不是有錯。
(像這樣的程式碼,用 Supabase 處理登入、註冊、登出和監聽使用者狀態。)
export const auth = {
// 登入
async signIn(email: string, password: string) {
return await supabase.auth.signInWithPassword({
email,
password,
})
},
// 註冊
async signUp(email: string, password: string) {
return await supabase.auth.signUp({
email,
password,
})
},
// 登出
async signOut() {
return await supabase.auth.signOut()
},
// 獲取當前用戶
async getCurrentUser() {
const { data: { user } } = await supabase.auth.getUser()
return user
},
// 獲取當前 session
async getCurrentSession() {
const { data: { session } } = await supabase.auth.getSession()
return session
},
// 監聽認證狀態變化
onAuthStateChange(callback: (event: string, session: unknown) => void) {
return supabase.auth.onAuthStateChange(callback)
}
}
在沒有 AI 的情況下,系統還能不能用呢?
工作中相關運作的邏輯有沒有被 AI 的細節綁死?
如何在抽象層設計時考慮未來的未知?
明天可能需要多模態(圖像+語音),抽象介面該怎麼設計?