HomeAbout Me

不要一看到重複的程式碼就把它殺掉 (DRY is about Knowledge:Code duplication is not the issue )

By Nissen Yeh
Published in Software philosophy
May 24, 2021
1 min read

什麼是 Dry ?

Dry 的意思是 Don’t Repeat Yourself

  • 工作上,一個效率的工作者,如果發現一件事要重複做 or 說很多遍,就可以把它標準化、文件化,避免自己忘記要重複研究或是溝通。

  • 工程上,一個工程師,如果在開發上發現一些重複的程式碼,就應該把它抽象共用出來。避免更改邏輯,都要重複去不同地方更動。

遇到重複的程式碼,時常產生殺掉的衝動

在剛學到 Dry (Don’t Repeat Yourself) 這個概念時,我覺得這概念很棒。沒錯,看到重複的程式碼,就應該殺掉。

但在實踐上,我其實會遇到很多為難和疑惑之處,例如,會想到

  • 「恩… 雖然這段 code 在不同的 class 重複了,但它就是個簡單數量判斷,有必要把它抽象出來嗎?(而且還抽象到一個遙遠的檔案中),這會不會太小題大作啊?」

  • 「這個 function 已經拆到,如果不去很遠的地方翻閱,不知道他在幹嘛了,真的還要再拆嗎?」

舉個例子,下面的程式碼中是有關於「購物車」跟「出貨」的邏輯

  1. 消費者在購物時,最多只能買 3 樣物品
  2. 商家在出貨時,最多只能出 3 個物品

看到這個 code 時,工程師可能會有個衝動「啊! addProduct 那段函式好重複」有個衝動很想要把它抽象出來,並且改寫為如下

寫完後,工程師覺得很滿意,心想「它很簡潔,它很棒!」

不要衝動!

DRY is about Knowledge 的作者 mathias verraes 告訴我們,這是「錯誤的衝動」,因為購物車(shoppingCart)跟出貨(ShipmentCart) 這兩段程式背後「設計意圖」是不同的。

  • 購物車會有購買限制,可能是因為這是個「限定商品」,所以只讓消費者買 3 個。
  • 會有出貨限制,可能是因為這是個「危險的化學產品」,所以一次出3個貨怕有風險

但未來,這些考量可能會不ㄧ樣,例如

  • 限定商品可能貨源變多,所以消費者可以開始買更多個
  • 因為有更安全的運送機制,所以出貨的限制可以變大,商家一次可以出更多貨

因為他們背後的「設計意圖」不同,因此這樣過度抽象的設計,導致未來環境變化時,購物車和出貨兩邊的邏輯難以改動並難以閱讀。

應該基於「設計意圖」,而不是基於「重複的表象」來重構程式碼

因此,Don’t repeat yourself 的原則不是「看程式碼重複,而是看程式碼背後的設計意圖」:

  • 如果兩段程式碼的設計,背後是基於同樣的理由或知識,那他們就會因為外在條件的改變而被一起更改。在這種情況下,讓兩段程式碼共用抽象邏輯是必要的(因為你總可能會忘記改到其中一個)

  • 相反的,如果兩段程式碼背後是建構於不同的理由或知識,他們就會因為不同狀況,獨立產生變化。這時候現在對他們的共用邏輯進行抽象就是沒有必要的。

“Don’t Repeat Yourself” was never about code. It’s about knowledge. It’s about cohesion. If two pieces of code represent the exact same knowledge, they will always change together. Having to change them both is risky: you might forget one of them. On the other hand, if two identical pieces of code represent different knowledge, they will change independently. De-duplicating them introduces risk, because changing the knowledge for one object, might accidentally change it for the other object.”

總結:要不要執行 Dry ,應該基於程式背後的意圖(intent),而不是僅僅是因為看到「重複的程式碼」的這個表象 (DRY is about Knowledge,Code duplication is not the issue)

參考

DRY is about Knowledge:Code duplication is not the issue :本篇例子與內容多來自於此篇文章


Previous Article
前端技術發展史,關注點分離的辯證:模板語言到 React 與 Vue

Nissen Yeh

Software Engineer

Topics

Software philosophy

Web development

Project

Free talk

Related Posts

Web(World Wide Web)的起源:為什麼 Tim Berner-lee 想要設計 Web?
April 20, 2022
3 min
© 2022, All Rights Reserved.

Quick Links

Advertise with usAbout Us

Social Media