Kent Beck 的「Once and Only Once」原則揭示軟體開發鐵律:任何邏輯片段——演算法、常數、文檔——應在系統中僅出現一次。重複代碼不僅導致版本不一致、責任分散、修改遺漏,更嚴重阻礙效能優化。某管理者曾誇耀程式員「複製模板稍改即完成新模組」,這種看似高效實則埋下維護地雷:除作者外無人能懂,連作者自己日後也難維護。
每個決策前自問:「這能為系統增加價值嗎?」Yes → 執行;No → 放棄。此為萬法之本,所有技術選型、架構設計最終服務於用戶價值交付。
簡單非偷工減料,而是經深思熟慮、反覆重構後的極致精簡。真正優雅的設計往往最簡單,但達到簡單需要嚴謹思考。簡單帶來易維護、低缺陷,是長期投資回報最高的品質。
Brooks 強調「概念完整性是系統設計最重要考量」;Stroustrup 指出「乾淨內部結構是可理解、可維護、可測試系統基石」;Booch 則說「唯有對系統架構有清晰掌握,才能發現通用抽象」。盲目複製貼上會陷入「大泥潭」,失去對系統整體的掌控力。
Kent Beck 言:「代碼不只給電腦看,更給人看。」混雜相似卻不同的重複代碼,讓後續維護者無法辨別異同、理解關聯。可讀性是專業素養的體現。
成功軟體壽命長,必須適應變化。開發時持續追問「如果……那麼……」,預留擴展點,而非硬編碼當前需求。但需警惕過度設計陷阱。
軟體模式是重用規劃的體現;重複代碼絕非計劃。系統化抽象、封裝變化點,才是真正的重用策略。
任何動作前先做清晰完整思考,即便結果錯誤,思考過程也沉澱經驗,利於後續學習把握同類問題。
針對不同重複形態,Fowler 《重構》書中提供標準解法:
原始碼中 asciiStatement() 與 htmlStatement() 結構高度相似(印表頭、遍歷項目、印表尾),卻將格式邏輯硬編碼。重構引入 Printer 介面與策略模式:
interface Printer {
String header(Invoice iv);
String item(LineItem line);
String footer(Invoice iv);
}
class AsciiPrinter implements Printer { ... }
class HtmlPrinter implements Printer { ... }
class Invoice {
public String statement(Printer pr) {
StringBuffer result = new StringBuffer();
result.append(pr.header(this));
for (LineItem each : items) result.append(pr.item(each));
result.append(pr.footer(this));
return result.toString();
}
}
核心邏輯集中於 statement(),格式細節委派給具體 Printer。新增輸出格式只需實作新 Printer,符合開放封閉原則。此例同時展示 Dispatch Interpretation 模式:statement 解碼內部結構,Printer 僅負責呈現。
消除重複非無腦追求「越小越好」。方法是復用最小單元,但過度拆解會增加調用開銷與維護負擔。判準在於:能否用「揭示意圖的名稱」精準命名該方法。唯當方法實現單一具體意圖時,才值得獨立成法。Fowler 與 Beck 的著作中闡述大量此類平衡藝術。
七大原則指引我們從「複製修改」的舒適區走向「抽象封裝」的專業領域。消除重複非目的,而是為獲得概念完整性、可維護性與擴展力。真正大師不寫重複代碼,而是設計讓重複無處遁形的架構。