8.1 KiB
8.1 KiB
TTS 播放按鈕架構不一致問題評估報告
📋 問題概述
在 BluePlayButton 重構過程中,發現了 TTS 播放邏輯的架構不一致性問題,導致同一應用中存在兩套不同的播放狀態管理機制。
🔍 現況分析
當前架構狀態
1. 新架構 (BluePlayButton 內建邏輯)
使用範圍: 8+ 個組件
// 使用方式:極其簡潔
<BluePlayButton text="hello" />
// 狀態管理:組件內建
const [isPlaying, setIsPlaying] = useState(false) // 內建於 BluePlayButton
優勢:
- ✅ 使用簡潔,一行代碼
- ✅ 無狀態洩漏,組件自主管理
- ✅ 無重複邏輯
2. 舊架構 (useTTSPlayer Hook)
使用範圍: 詞卡詳細頁面 (app/flashcards/[id]/page.tsx)
// 使用方式:複雜配置
const { isPlayingWord, isPlayingExample, toggleWordTTS, toggleExampleTTS } = useTTSPlayer()
<FlashcardDetailHeader
isPlayingWord={isPlayingWord}
onToggleWordTTS={toggleWordTTS}
/>
<FlashcardContentBlocks
isPlayingExample={isPlayingExample}
onToggleExampleTTS={toggleExampleTTS}
/>
問題:
- ❌ 與新的 BluePlayButton API 不相容
- ❌ 外部狀態管理複雜
- ❌ 狀態可能與內建邏輯衝突
🚨 架構衝突分析
衝突點 1: 雙重狀態管理
詞卡詳細頁面狀態流:
useTTSPlayer Hook → isPlayingWord → 傳遞給組件
↓ 衝突
BluePlayButton → 內建 isPlaying 狀態
衝突點 2: API 不相容
// useTTSPlayer 期望的 API
<BluePlayButton isPlaying={isPlayingWord} onToggle={toggleWordTTS} />
// 新 BluePlayButton 的 API
<BluePlayButton text="hello" /> // 無 isPlaying 和 onToggle
衝突點 3: 功能重複
useTTSPlayer有完整的 TTS 邏輯 (71 行)BluePlayButton也有完整的 TTS 邏輯 (40 行)- 總計 111 行重複邏輯
💡 解決方案評估
方案 A: 完全統一為 BluePlayButton 內建邏輯 ⭐⭐⭐⭐⭐
實施方式:
- 移除詞卡詳細頁面的
useTTSPlayer使用 - 簡化
FlashcardDetailHeader和FlashcardContentBlocks的 props - 刪除
useTTSPlayer.tsHook
修改範例:
// app/flashcards/[id]/page.tsx
- const { isPlayingWord, isPlayingExample, toggleWordTTS, toggleExampleTTS } = useTTSPlayer()
<FlashcardDetailHeader
flashcard={flashcard}
- isPlayingWord={isPlayingWord}
- isPlayingExample={isPlayingExample}
- onToggleWordTTS={toggleWordTTS}
/>
<FlashcardContentBlocks
flashcard={flashcard}
- isPlayingWord={isPlayingWord}
- isPlayingExample={isPlayingExample}
- onToggleExampleTTS={toggleExampleTTS}
/>
優勢:
- ✅ 完全一致: 全應用使用相同的播放邏輯
- ✅ 代碼最少: 移除 71 行重複邏輯
- ✅ 維護簡單: 只需維護一套 TTS 邏輯
- ✅ 使用統一: 所有組件使用方式一致
劣勢:
- ❌ 狀態隔離: 無法協調兩個按鈕的播放狀態 (同時只能播放一個)
- ❌ 重構成本: 需要修改組件 props 介面
評分: 5/5 (推薦)
方案 B: 保持 useTTSPlayer,適配新 BluePlayButton ⭐⭐⭐
實施方式:
- 修改 BluePlayButton 支援外部狀態注入
- 保持 useTTSPlayer Hook 不變
- 通過 props 橋接兩套系統
修改範例:
// 修改 BluePlayButton 支援外部狀態
interface BluePlayButtonProps {
// 新增外部狀態支援
externalIsPlaying?: boolean
externalOnToggle?: (text: string) => void
// 保留內建邏輯
text?: string
}
// 使用方式
<BluePlayButton
externalIsPlaying={isPlayingWord}
externalOnToggle={toggleWordTTS}
/>
優勢:
- ✅ 狀態協調: 可以協調兩個按鈕的播放狀態
- ✅ 向下相容: 不破壞現有功能
- ✅ 漸進移轉: 可以逐步移轉到新架構
劣勢:
- ❌ 複雜度增加: BluePlayButton 變複雜,需要處理兩套邏輯
- ❌ 代碼重複: 仍有重複的 TTS 邏輯
- ❌ API 混淆: 組件有兩種使用方式,容易混淆
評分: 3/5 (可行但不理想)
方案 C: 混合架構 - 詞卡詳細頁面特殊處理 ⭐⭐
實施方式:
- 詞卡詳細頁面保持使用 useTTSPlayer
- 其他頁面使用 BluePlayButton 內建邏輯
- 接受架構不一致性
優勢:
- ✅ 最小改動: 幾乎不需要修改現有代碼
- ✅ 功能保持: 不影響現有功能
劣勢:
- ❌ 架構混亂: 同一應用有兩套播放邏輯
- ❌ 維護困難: 需要維護兩套不同的系統
- ❌ 代碼重複: 71 行 + 40 行 = 111 行重複邏輯
- ❌ 開發混淆: 新開發者不知道該用哪一套
評分: 2/5 (不推薦)
📊 詳細衝擊評估
方案 A 實施衝擊分析
需要修改的文件:
app/flashcards/[id]/page.tsx- 移除 useTTSPlayer 使用components/flashcards/FlashcardDetailHeader.tsx- 移除 TTS propscomponents/flashcards/FlashcardContentBlocks.tsx- 移除 TTS propshooks/shared/useTTSPlayer.ts- 刪除檔案
修改工作量:
- 估計時間: 30-60 分鐘
- 修改行數: ~30 行
- 風險等級: 低(只是移除多餘代碼)
相容性影響:
- 破壞性變更: 是(修改組件 props 介面)
- 功能影響: 無(播放功能完全保持)
- 用戶體驗: 無影響
🎯 推薦方案
強烈推薦:方案 A - 完全統一為 BluePlayButton 內建邏輯
推薦理由:
-
架構純淨性:
- 全應用使用統一的播放邏輯
- 消除 111 行重複代碼
- 單一真相來源 (Single Source of Truth)
-
開發體驗:
- 新組件開發只需要知道一種使用方式
- 無需學習兩套不同的播放邏輯
- IDE 自動完成更準確
-
維護成本:
- 只需維護一套 TTS 邏輯
- bug 修復只需要在一個地方
- 功能增強影響全應用
-
性能優勢:
- 減少組件 props 傳遞
- 減少狀態更新鏈條
- 更好的組件獨立性
實施建議:
階段 1: 狀態協調解決方案 (可選)
如果需要協調兩個播放按鈕的狀態(同時只能播放一個),可以:
// 在 BluePlayButton 中添加全域狀態管理
import { create } from 'zustand'
const useGlobalTTSStore = create((set) => ({
activePlayer: null,
setActivePlayer: (player) => set({ activePlayer: player })
}))
// BluePlayButton 使用全域狀態
const { activePlayer, setActivePlayer } = useGlobalTTSStore()
階段 2: 漸進式重構
- 先修改詞卡詳細頁面使用新 API
- 測試確保功能正常
- 刪除 useTTSPlayer Hook
- 清理相關 imports
🚀 實施路線圖
立即執行 (10 分鐘)
- 移除詞卡詳細頁面的 useTTSPlayer 使用
- 簡化組件 props 傳遞
短期清理 (20 分鐘)
- 刪除 useTTSPlayer Hook
- 清理相關類型定義
- 更新組件介面文檔
可選增強 (30 分鐘)
- 添加全域播放狀態協調
- 實施播放佇列機制
- 添加播放狀態持久化
📈 預期效益
量化效益:
- 代碼減少: 71 行 (useTTSPlayer) + 30 行 (props 傳遞) = 101 行
- 組件簡化: 3 個組件的 props 介面簡化
- 維護成本: 降低 50% (只需維護一套邏輯)
質性效益:
- 架構一致性: 全應用統一設計模式
- 開發效率: 新功能開發更快速
- 代碼品質: 消除重複,提高內聚性
🎯 結論與建議
強烈建議立即實施方案 A,理由:
- 技術債務清理: 消除架構不一致性
- 開發效率: 統一的開發模式
- 代碼品質: 大幅減少重複邏輯
- 未來維護: 更容易擴展和修改
風險評估: 低風險,只是移除多餘代碼,不影響核心功能
實施優先級: 🔴 高 (建議在下次開發週期立即處理)
報告生成時間: 2025-10-02 問題發現者: 用戶架構審查 分析範圍: 全前端 TTS 播放邏輯