原型模式通過複製現有實例(原型)來創建新對象,而非通過構造函數實例化。適用於對象創建開銷大、構造參數複雜、或需動態配置對象狀態的場景。
Java 通過實現 Cloneable 接口並覆寫 clone() 實現淺/深複製:
public abstract class AbstractSpoon implements Cloneable {
private String spoonName;
// getter/setter 省略
@Override
public Object clone() {
try {
return super.clone(); // 淺複製
} catch (CloneNotSupportedException e) {
throw new AssertionError(); // 不可能發生
}
}
}
public class SoupSpoon extends AbstractSpoon {
public SoupSpoon() { setSpoonName("Soup Spoon"); }
}
public class SaladSpoon extends AbstractSpoon {
public SaladSpoon() { setSpoonName("Salad Spoon"); }
}
// 客戶端
AbstractSpoon spoon1 = new SoupSpoon();
AbstractSpoon spoon2 = (AbstractSpoon) spoon1.clone(); // 克隆新對象
super.clone() 默認行為,引用類型字段共享同一對象。clone() 中手動複製引用字段,或使用序列化/JSON 反序列化實現完全隔離。public class SpoonFactory {
private Map<String, AbstractSpoon> prototypes = new HashMap<>();
public SpoonFactory() {
prototypes.put("soup", new SoupSpoon());
prototypes.put("salad", new SaladSpoon());
}
public AbstractSpoon createSpoon(String type) {
return prototypes.get(type).clone();
}
}
原文附帶一個完整的微信式語音錄製控件實現,包含錄音管理、UI 交互、播放控制。核心類結構:
| 類 | 職責 |
|---|---|
AudioManager | 單例,封裝 MediaRecorder 錄音、音量級獲取、文件管理 |
AudioRecorderButton | 繼承 Button,處理長按/滑動取消/釋放發送邏輯,狀態機控制 UI |
DialogManager | 管理錄音彈窗:錄音中/取消/時間過短/音量級動畫顯示 |
MediaManager | 單例,封裝 MediaPlayer 播放/暫停/釋放 |
RecoderAdapter | ListView 適配器,動態調整項寬度展示錄音時長 |
MainActivity | 綁定錄音按鈕回調,管理錄音列表、播放動畫與生命周期 |
AudioManager.prepareAudio() 異步準備 → Handler 收到 MSG_AUDIO_PREPARED 顯示彈窗 → 開啟子線程定時獲取音量級更新 UI。onFinish(seconds, filePath) 添加列表。MediaManager.playSound 播放,配合幀動畫顯示播放狀態。Context.getExternalFilesDir() 替代硬編碼 /storage/sdcard0/,適配 Android 10+ 分區存儲。MediaRecorder/MediaPlayer 操作需嚴格遵循狀態機,異常分支務必 reset()/release() 防止資源洩漏。Handler 切換主線程更新 UI,符合 Android 單線程模型。本文雙軌並行:前半部講解 Java 原型模式核心機制與最佳實踐;後半部提供生產級 Android 語音錄製控件完整源碼與架構分析。兩部分雖業務無關,均展示了「模式指導實現、代碼服務業務」的工程思維。