遵循 DRY 原則的反思:當程式碼告訴我們「複製」不是最佳解

2025 年 04 月 11 日

從一段重複程式碼出發,探討「複製貼上」這個看似高效但可能帶來長期問題的操作。文章介紹 DRY(Don't Repeat Yourself) 原則作為編程思維方式,展示重構優化的實例,並分析我們傾向複製而非抽象的原因。強調在實際工作中找到 DRY 原則應用的平衡點。

Web Develop

一個工程師的日常反思

緣起:一段重複的程式碼

今天在修改使用者需求時,意外發現系統中有這麼一段程式碼:

if (keyValuePairs["BuHead"] == keyValuePairs["BuHead2"]) {
    keyValuePairs["BuHead2"] = string.Empty;
}

if (!string.IsNullOrEmpty(keyValuePairs["BuHead2"])) {
    if (string.IsNullOrEmpty(keyValuePairs["BuHead"])) {
        keyValuePairs["BuHead"] = keyValuePairs["BuHead2"];
        keyValuePairs["BuHead2"] = string.Empty;
    }
}

if (keyValuePairs["SBuHead"] == keyValuePairs["SBuHead2"])
{
    keyValuePairs["SBuHead2"] = string.Empty;
}

if (!string.IsNullOrEmpty(keyValuePairs["SBuHead2"]))
{
    if (string.IsNullOrEmpty(keyValuePairs["SBuHead"]))
    {
        keyValuePairs["SBuHead"] = keyValuePairs["SBuHead2"];
        keyValuePairs["SBuHead2"] = string.Empty;
    }
}

看到這段程式碼,我突然有種莫名的似曾相識感。這種感覺不僅僅來自於程式碼本身,更像是我們生活中常見的一種現象。

複製貼上:程序設計師的救命稻草還是隱形殺手?

「Ctrl+C,Ctrl+V」——這可能是每個程式設計師最熟悉的快捷鍵組合。多少次在趕項目時,我們複製了一段程式碼,修改了幾個參數,然後就繼續前進?這種操作簡單、快速,而且...看起來很有效率。

但就像吃速食一樣,短期內填飽了肚子,長期卻會帶來健康問題。程式碼中的重複就是這樣的「速食」。

DRY 原則:不只是一個編程理念

DRY(Don't Repeat Yourself)不僅僅是一個撰寫原則,它更像是一種生活哲學。

當我把上面的程式碼重構為:

private void NormalizeKeyValuePairs(IDictionary<string, string> keyValuePairs, string primaryKey, string secondaryKey)
{
    if (keyValuePairs[primaryKey] == keyValuePairs[secondaryKey])
    {
        keyValuePairs[secondaryKey] = string.Empty;
    }

    if (string.IsNullOrEmpty(keyValuePairs[primaryKey]) && !string.IsNullOrEmpty(keyValuePairs[secondaryKey]))
    {
        keyValuePairs[primaryKey] = keyValuePairs[secondaryKey];
        keyValuePairs[secondaryKey] = string.Empty;
    }
}

然後簡單地調用:

NormalizeKeyValuePairs(keyValuePairs, "BuHead", "BuHead2");
NormalizeKeyValuePairs(keyValuePairs, "SBuHead", "SBuHead2");

這種改變不僅僅是程式的變化,更是一種思維方式的轉變。

反思:我們為何總是傾向於複製?

思考一下,為什麼我們總是傾向於複製而不是抽象?

  1. 時間壓力 — "趕緊完成,沒時間重構了!"
  2. 惰性思維 — "能用就行,為什麼要多此一舉?"
  3. 未知恐懼 — "現在的寫法我很熟悉,改了萬一出問題怎麼辦?"
  4. 缺乏全局視角 — "我只負責這部分,其他地方怎麼樣與我無關。"

這些理由聽起來很熟悉,對吧?它們不僅適用於程式,也適用於我們日常生活中的許多決策。

當 DRY 原則遇上實際工作

在實際工作中,DRY 原則並不總是那麼容易執行。有時候,追求 DRY 可能會導致過度抽象,使程式變得更加複雜而難以理解。

就像做菜一樣,適量的調料能提升美味,過多則會破壞食物的本味。同樣,適度的 DRY 能提高程式品質,過度則可能適得其反。

關鍵是找到平衡點。對於上面的例子,抽象出一個方法是合理的,因為:

  1. 邏輯完全相同,只是操作的對象不同
  2. 抽象後的方法清晰明了,不增加理解難度
  3. 未來可能有更多類似的操作需要這種邏輯

程式之外:DRY 在生活中的啟示

DRY 原則其實告訴我們一個更深層次的道理:系統化思考的重要性。

當我們遇到重複的任務時,不妨停下來問自己:
- 這是否是一個可以抽象為通用流程的任務?
- 我是否可以創建一個工具或模板來簡化這個過程?
- 這種重複是否暗示了系統設計上的缺陷?

無論是編寫程式、制定工作流程還是安排日常生活,這種思考方式都能帶來巨大的效率提升。

刷寶遊戲:當「複製」成為主流時失去的樂趣

說到「複製」與「創新」的平衡,我不禁想到現在流行的刷寶遊戲,比如《暗黑破壞神 4》。這類遊戲本應是個人探索與創造的天堂,但現實往往是:

  1. 玩家上網搜索「最強裝備搭配」
  2. 照著攻略一步步複製別人的配置
  3. 按照指定路線刷怪升級
  4. 最後,大家都使用著相同的角色、相同的裝備組成、相同的技能...

多麼諷刺啊!為了放鬆玩遊戲,結果卻被「最佳實踐」所統一。遊戲變成了另類的「交作業」,失去了原有的探索樂趣。

這不正是我們在程式中過度追求「標準模式」時的寫照嗎?當所有人都在模仿而不是創新時,我們是否也失去了撰寫程式時的思考解決問題的樂趣?

平衡模仿與探索

就像在撰寫程式中,我們需要平衡 DRY 原則與程式靈活性一樣,在遊戲中,我們也需要平衡「效率」與「樂趣」:

  • 學習他人經驗:了解主流玩法,吸收有用的策略(就像學習設計模式)
  • 保持自我探索:嘗試獨特的搭配,發現遊戲未被挖掘的可能性(就像嘗試新的撰寫方法)
  • 享受過程:記住遊戲的核心是樂趣,不僅僅是達成目標(就像撰寫的樂趣不僅在於完成任務,思考解決方法也是一部分的享受)

或許 DRY 原則真正想告訴我們的:「不要盲目重複」,無論是程式還是生活方式。

結語:從一段程式碼看人生

從一段簡單的重複程式碼出發,我們可以看到它反映的不僅是撰寫習慣,還有我們處理問題的思維模式。

DRY 原則提醒我們:
- 尋找模式,抽象共性
- 不要滿足於表面的解決方案
- 系統性思考能帶來長期的效益

下次當你準備按下「Ctrl+C」時,也許可以停頓一下,想想是否有更優雅的解決方案。因為無論是在程式還是生活中,真正的效率來自於思考,而不是機械地重複。

寫完這篇文章,我突然覺得,我的咖啡杯空了,是時候寫一個自動補充咖啡的函數了...如果只有這麼簡單就好了!