尤 川豪   ·  3週前
Exp. 1,382  ·  170 貼文  ·  130 留言

程式抽象化設計 vs 被孩子們搗亂過的幼稚園遊戲間

寫程式的時候,常常聽到 abstraction。

什麼是 abstraction?今天試著用一個小例子解釋:被孩子們搗亂過的幼稚園遊戲間。

Abstraction 很困難

要做出優秀的 abstraction 是非常困難的。

主因兩個。第一:它很花時間,需要在開發之前有通盤的架構設計

第二:它很吃經驗,通常需要對類似功能、模組有過開發經驗 才能做出比較漂亮的 abstraction。

除此之外,如果沒辦法做出優秀的 abstraction,卻硬要做出看似精細的 abstraction,通常比不做更慘。

錯誤的 abstraction 比沒有 abstraction 還糟糕,直接增加整體系統的理解難度、成本。

這點跟寫測試的時候,剛剛好是相反

寫測試是:有總比沒有好、只測到簡單陽春的情境,也比完全不測好。

abstraction 是寧可你不做、你 duplicate code,也不要亂把不同概念的 code 抽象到同一個地方(模組、類別、函式之類的)

以檔案架構來說,如果不確定,那麼做出幾個扁平、肥肥的檔案、資料夾

也比深層、複雜,但是設計錯誤的檔案結構來得好。

扁平寬大 vs 深層複雜

哪種比較好理解?不妨以整理散落一地的雜物做比喻。想像幼稚園的遊戲間剛被孩子們搗亂過。

老師要整理的時候,一開始沒有把握,先只做簡單的分類,把同類的東西收在一起即可(玩具放一起、零食放一起、故事書放一起)。

可想而知會變成幾個大箱子、大櫃子,這就是扁平寬大

雖然很隨便,但是做起來快速、方便,而且效果不差了!

接著要進一步整理的話,如果收拾同樣東西好幾次了,有經驗了,就可以進一步分類

玩具再去細分不同類型、不同部位、零件,故事書也可以分類型、出版社、甚至是封面顏色,可以有各種收法,這就是深層複雜

反之,如果一開始就硬要用幾個小箱子、小隔間把玩具、零食硬是分類到不同地方

做出錯誤的深層複雜 abstraction,那麼下次要找東西時,只會超難找而已!

整理的方式就是 abstraction,好不好找到就是 maintainability

好不好理解是人類的事情,跟電腦無關

不管是程式概念、還是檔案結構上的設計,都是給人看的。對電腦來說,沒有好不好理解的問題。

所謂抽象化、模組化、重用性、可維護性,全部只跟人有關。

對電腦來說,都只是層層 compile 之後的 1 跟 0 而已,所以,abstraction 的時候主要考慮人,並且常常需要伴隨著出現一些效能的損失。

Abstraction 通常伴隨著效能的損失

把一個東西拆分成多個,就算是漂亮的拆分,也會伴隨著重新組織彼此起來時的 overhead

以幼稚園的例子來說,雖然叫孩子們每次下課就把東西收好是一個不錯的主意,但是完全不去收其實也不錯呀。孩子們隔天上學時回到老地方順手就能繼續玩了,說不定連坐在附近的朋友都一樣。

這種每天都收起來、隔天再拿出來的力氣耗費,就是 overhead,對電腦來說,就是效能的損失。

效能的損失有時大有時小,有時這需要跟 abstraction 帶來的好理解做權衡取捨。

通常碰到跟資料庫相關的 abstraction 最需要小心取捨,需要審慎評估伴隨的 overhead 是否會過大。

不過話說回來,不做 abstraction 的話,孩子們隔天進去時要記得昨天他們坐在哪、玩什麼、哪個玩具是誰在玩。搞錯的話會吵架、老師會傷腦筋。省下這個記得的功夫,就是 abstraction 的好處。

好的 abstraction 讓程式直觀、易懂、好讀,用起來就跟看起來預期的一樣,很爽的。

軟體的成長,也需要跟著強化 abstraction

看到這邊也許會覺得,既然做錯 abstraction 那麼糟,不如少做少錯。其實也不然。

過份的 abstraction 很糟,欠缺 abstraction,長遠來看也不行,根本是新手寫的程式碼。

遊戲間的東西散落一地卻收都不收,當孩子們不多、遊戲間不大的時候還沒關係,至少老師知道大家在玩什麼就行了。

孩子們變多、遊戲間很大的時候就不行了,絕對不可行。

有句話是這樣說的

The secret to building large apps is never build large apps.

Break your applications into small pieces.

Then, assemble those testable, bite-sized pieces into your big application.

小系統來說,就是拆分到適當的檔案、類別、函式裡頭。大系統來說,就是做幾個模組、系統,讓彼此分工合作,互相獨立而又協調。

當軟體逐漸成長的時候,或說是一開始設計與組織大型軟體的時候,終究是需要有越來越強的 abstraction,才能讓系統保持好維護。

結論

被孩子們搗亂過的幼稚園遊戲間到底要不要整理?要多頻繁地去整理?要收拾分類到什麼程度?

這個問題就是我想說的:abstraction 沒有標準答案。

堅持在開發初期就要有完整 abstraction 而不顧慮伴隨的時間消耗是不對的:這拖慢了開發速度,而且,還有可能出現錯誤的 abstraction。別忘了商業需求、技術規格的可能改變,這保證了 abstraction 會出現錯誤的可能。

而對 abstraction 毫無要求、毫無追求也是不對的:這讓開發出現瓶頸、每次都需要記住整體才能夠理解,最後出來的程式碼毫無優雅可言。令人一看就懂的漂亮 abstraction,與之伴隨的藝術性、工藝精神,是每個工程師值得追求的目標。

(完)

  分享   共 1,565 次點閱
共有 0 則留言
您的留言
尤 川豪
Exp. 1,382  ·  170 貼文  ·  130 留言

關於作者

Devs.tw 作者,喜歡分享&建造新東西的工程師。

技術部落格:轉個彎日誌

歡迎在 Facebook 追蹤我!

不定期分享有趣技術文章!