iT邦幫忙

2021 iThome 鐵人賽

DAY 1
3
Software Development

成為乾淨的開發者吧! Clean Code, Clean Coder, Clean Architecture 導讀之旅系列 第 1

Day 01: 【序】– 架構與設計、代碼、工程師

「你因為兩個原因來讀這本書:首先,你是位程式設計師。再者,你想成為一位更好的程式設計師

取自: Clean Code (p.1)

前言

  • 本系列文筆者嘗試將大神 Robert C. Martin (aka Uncle Bob,為敏捷軟體開發的初代推手之一、SOLID 設計原則提出者) 筆下三本經典大作濃縮,並以簡單的程式範例及補充,將 "Clean" 開發理念分享給各位讀者。接下來我們將依序導讀:
    • 無瑕的程式碼:敏捷軟體開發技巧守則 (Clean Code)
    • 無瑕的程式碼番外篇:專業程式設計師的生存之道 (The Clean Coder)
    • 無瑕的程式碼-整潔的軟體設計與架構篇 (Clean Architecture)

什麼是 Clean Architecture?

  • 整潔軟體架構 (Clean Architecture) 的目的說穿了只有一個 - 最小化『建置和維護系統所需的人力』
    或者,我們也許能說,是為了最小化在整個軟體專案生命週期中,為了達到相對應業務需求所需投入的資源及成本 (包含資金、開發 & 維運人力、時間、運算資源...等)

    "The goal of software architecture is to minimize the human resources required to build and maintain the required system."

  • 並不是為了一昧 解耦 (Decoupling) 而硬是為軟體畫分出無數的層次 (Layers)邊界 (Boundaries) 。這導致為了完成很簡單的需求,卻需要一併為沿途來回所經過的無數層次處理相對應的資料結構和通訊方法

    「實際上,最大的錯誤是 『過度架構 (Over-Architecture)』 。層數比我在這裡描述的還要多許多,這大大降低了團隊的生產力。整個工具被廢棄了,取而代之的是一個小團隊所編寫的一個可愛小應用程式」

  • 也不是為了避免程式碼重複 (Duplicate) 而不考慮元件 (Component) 和類別 (Class) 的設計原則、依賴關係...等,直接將所看到的共用程式碼都提取到父類別或者某些介面。導致軟體的 可擴展性 (Extensibility) 下降

    「架構師往往會陷入一個陷阱 - 這個陷阱取決於對重複 (Duplication) 的恐懼」

  • 除此之外,魔鬼也藏在實作細節中。你能想像團隊只要誤用某一種修飾子 (Access Modifier),就有可能導致精心設計的架構遭到嚴重破壞嗎?

    "The net result is that if you ignore the packages (because they don’t provide
    any means of encapsulation and hiding), it doesn’t really matter which architectural style you’re aspiring to create."

  • 而談到細節 (Details),現代軟體工程提供了各式各樣的 Web & GUI、Databases、Frameworks,身為好的軟體架構師,又該如何考量呢?

    「優秀的架構師會小心地將細節從策略中分離出來,使策略與細節測底脫鉤,不以細節為依據。盡可能地延緩有關細節的決定」

最後以軟體架構與設計作為前言結尾,現代軟體工程隨著時間發展出了許多的架構...

  • 水平橫向分層架構 (Horizontal Layer Architecture)
  • 服務導向架構 (Service-oriented architecture)
  • 六角形架構 (Hexagonal Architecture)
  • C4 Model (Context, Containers, Components, and Code)
  • 領域驅動設計 (Domain-Driven Design)
  • 整潔的軟體架構 (Uncle Bob's Clean Architecture)
  • ...

我們是否能歸納出一些共通的本質呢?

「本書就是要來講述這些規則的 - 那些永恆、不變的規則」

在後面的文章,我們會慢慢開始揭露這些如蜂巢、如洋蔥般的層層設計架構。在這之前我們先來思考......

https://ithelp.ithome.com.tw/upload/images/20210919/20138643jJqyIqpGg0.png

為什麼要解耦? (Decoupling)

  • 雖然過度追求解耦可能衍生過度設計 (Over-Design) 的問題,了解耦合性相關的議題仍然是學習軟體架構的重要入門課

  • 軟體模組間的依賴性 (Dependency) 高會發生什麼? 直接看一個真實的例子:

    • 80年代某不願具名軟體公司的內部統計資料:
      工程人員的增長:
      https://ithelp.ithome.com.tw/upload/images/20210916/20138643ruCgKosSCZ.png
      同一時期的生產力:
      https://ithelp.ithome.com.tw/upload/images/20210916/20138643jCn7ciTGtn.png
      每行程式碼的平均成本:
      https://ithelp.ithome.com.tw/upload/images/20210916/20138643oyMtyx36EA.png
  • 我們可以看到

    • 隨產品釋出的次數與版本增加,參與專案的人員數、產值,以及開發成本之間的非線性關係
    • 即便工程師們持續加班,程式的產能幾乎沒有增加
    • 此時,專案重構的成本已經大於打掉重建了......

「當對程式碼的整潔程度或設計的結構沒有多少想法時,那你就會跟這條曲線一樣走到最終悲慘的結局」

取自: Clean Architecture (p.6)


為什麼要寫 Clean Code?

承上,甚至我們可以看到更嚴重的後果:

「我知道有一間公司在 80 年代後期開發了一個殺手級應用,但後來發行的週期開始拖長,程式裡的錯誤也無法在下次發行之前修復,程式載入的時間與崩潰機率也愈來愈長和高。不久,這家公司就倒閉了。我問他當時發生了什麼...」

「急於將產品上市,導致他們的程式碼變得一團糟,當他們加入愈來愈多的產品特點時,程式碼就變得愈來愈糟糕,一直到他們再也無法管理這團混亂。劣質的程式碼導致了這家公司的倒閉

取自: Clean Code (p.3)

乾淨的代碼深入實作細節來探討如何透過編程風格與慣例,寫出好讀 (Readable)、易改、易維護的程式碼。接下來的導讀中,我們將從最基本的「命名」、「註解」、「縮排」開始探討好讀的程式碼應該要注重哪些細節。事實上,只要引入整齊一致的縮排和命名風格就能夠大大地增加程式碼的可讀性了

至於什麼叫做 「乾淨的程式碼」 ? 判別指標其實很單純,最小化它就是了:

「唯一有效的「程式品質」度量單位: 每分鐘罵髒話的次數 (WTFs/m)
https://ithelp.ithome.com.tw/upload/images/20210916/20138643xhPH8kRFj9.jpg

什麼是 Clean Code?

上述指標純屬玩笑,讓我們援引各方大師的說法。更具體點來說...

「Clean Code 是可被原作者以外的開發者閱讀與增強的。它應當包含單元測試驗收測試

「減少重複、具有高度的表達力、並及早建立簡單抽象概念,這些對我而言,就是撰寫 Clean Code 的方法」

「當每個你看到的程式,執行結果都與你想得差不多,你會察覺到你正工作在 Clean Code 之上」

取自: Clean Code (pp.10-13)


為什麼要當 The Clean Coder?

最後是軟性議題。回歸開發者本身,面對種種的開發需求、甚至雜事、無效率的會議、何時該說 Yes or No?、專案時程與進度的控管、團隊協作開發......等,也是作為一位工程師非常重要的一部分。在此篇中不會提到任何程式碼,筆者可將其當作軟體工程師的職涯經驗談,至於書中內容是否適用於每種情況則見仁見智了

「學會作一位 Clean Coder 比學會寫出 Clean Code 還要難的多」

此外,書中作者對於 「流態區 (The Flow Zone) 」 的看法也是滿值得思考
究竟過於高度的專注是否真的有利於長期的程式開發呢?

「關於『高效率狀態』人們已經寫了很多,通常被稱之為『流態(flow)』。這是一種意識高度專注但思維視野卻會收斂到狹隘的狀態」

「他們會感到自己絕無錯誤、感到自己效率極高。然而這種意識狀態並非真的極為高效,這其實只是一種淺層冥想。為了追求所謂的速度,理性思考的能力會下降。你其實沒有顧及全域,你很可能會做出一些後來不得不摧毀的決策」

取自: The Clean Coder (p.95-96)

最後作者談到對 「會議」 的看法時,更是讓人會心一笑:

關於會議,有兩條真理:

  1. 會議是必須的
  2. 會議浪費了大量時間

取自: The Clean Coder (p.148)

未來我會持續、緩慢地反覆編輯並重構這一系列文章,為各位導讀這三本書的精隨。歡迎讀者每隔一段期間就來翻閱一下,或者一起交流~


後記

2024.02.11
讀這系列書並撰寫心得文,是碩畢剛出社會的第一年,當時還在寫 Web
後續轉職到了 IC 廠寫軟韌體兩年,看到的又更不一樣了.

再回頭看當初的文章,發現了許多可以再修正及勘誤的地方
今年預計再找時間,慢慢把重寫 Day01, Day02... 文章排進行事曆裡

2021.09.16
下筆的當下就開始極度後悔選這個主題了QQ... 要想一次把三本書中的內容都融會貫通並寫成系列文章發布,對筆者本身的程式底蘊和內功、職涯經驗有很高的要求。以我目前的程度,這系列文只能算是心得紀錄而已,對 "Clean" 理念的詮釋如有不足,敬請各位大神們包涵 ( _ _ )


下一篇
Day 02: 給全端開發者的 Coding Conventions & Style Guide 補充
系列文
成為乾淨的開發者吧! Clean Code, Clean Coder, Clean Architecture 導讀之旅31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
s951080603
iT邦新手 5 級 ‧ 2022-11-15 00:06:57

您好,小弟為非本科系的學習者,
想詢問偶爾會看到大家在討論一些比如說:要會定義問題邊界 之類的詞,
因為本身並非本科系,
想請教您若想補齊這類知識應該要往哪些關鍵字去搜尋或哪些課去學習呢?

JC iT邦新手 2 級 ‧ 2022-11-17 23:11:40 檢舉

哈囉~
我當初也是從商管科系零基礎開始轉行資工的,很能體會初學者毫無方向,想 Google 也不知道關鍵字該怎麼下的狀況

您指的 "補齊這類知識" 是指想補齊哪一個領域呢?
假設你還在學生階段的話,其實很建議至少要好好把 "資料結構"、"作業系統" 這二個科目好好的讀過一遍,打下基礎

建議初學者可以去看講師已經整理好的開放式課程 (或是 Udemy 買課也可以)。每個單元一定都會提到許多關鍵字和概念,有不懂的地方就可以一直拆解問題,不斷的Google搜尋找答案,如果能找到什麼課程交流討論區之類的社群,學習效果會更好~

隨便推薦一個: https://ocw.nthu.edu.tw/ocw/index.php?page=course&cid=141

假設你已經出社會,是有目的的想要轉行的話,其實建議針對某領域 (例如前端開發) 直接報名付費的套裝課程,到了學院後就會有很多講師跟同學能帶著你,幫你解答問題,也比較節省時間

先謝謝您的回覆,
我目前是明年畢業的大四生,
算是勉強有碰到本科系邊的通訊系,
但系上軟體課程較不扎實,
加上自己之前比較混···,
對資結、演算法只能算是聽過課而已,
現在規劃是朝Java後端準備,
按著 roadmap.sh 網站提供的後端路線圖自學,
預計先把 Spring Boot 框架摸熟,
做一個side project 後,
再回頭補資結、作業系統,
因為就目前而言,
考量自身能力不適合直接挑戰外商公司,
所以著重於實務方面去學習,
至於 leetcode 感覺會是等自己有空閒時間再去刷的東西。

對了,
最近在學 Spring Boot 時,
有看到微服務架構以及系上下學期課程有服務導向架構,
因此才會找到您這篇文章,
但感覺自身能力還有點太淺,
只能先大致看過,
將知識點筆記起來,
後續再回頭補齊!
感謝您。

JC iT邦新手 2 級 ‧ 2024-02-11 00:41:35 檢舉

感謝分享~

沒意外的話,您現在應當已出社會或正在念碩?
看您列出的 roadmap 及方向都滿明確的,抱持著願意持續精進和學習的熱忱,一定會愈來愈厲害的!

0
geliswu
iT邦新手 5 級 ‧ 2023-06-07 14:47:22

您好,感謝您的分享,獲益蠻多。

另外提供個小小建議,就是當中您提到的

.領域驅動設計 (Domain-Driven Design)

嚴格來說,DDD 應該不算是架構的種類,它應該是種方法論,因為 DDD 並不提供架構的對應、也沒有明確地要你使用用何種架構來設計,DDD 的戰術也只是初步提供一些指引,像是 Application Services, Domain Services 或是 Entity 與 Value Object 等,它只是告訴你在 DDD 的架構裡大致可能需要那些元素來組成 或 完成 DDD 的架構設計,但你可以自由選擇用六角架構來設計或完成 DDD 的主要架構、也可以使用整潔架構 Clean Architecture 來設計 DDD 的軟體架構。

大致以上小小建議

非常謝謝您的分享!

Gelis

以下我個人簡介

部落格 (Gelis 技術隨筆):
http://gelis-dotnet.blogspot.tw
https://www.dotblogs.com.tw/gelis/

FB 社團 (軟體開發之路):
https://www.facebook.com/groups/361804473860062/

FB 粉絲團 (Gelis 的程式設計訓練營):
https://www.facebook.com/gelis.dev.learning/

我講授過的課程 SlideShare:
https://www.slideshare.net/GelisWu

Github:
https://github.com/wugelis

JC iT邦新手 2 級 ‧ 2024-02-11 00:35:23 檢舉

非常感謝大大的回應!

又工作了兩年回頭看當初的拙作,確實又發現了許多能勘誤及有待改進的地方

時間允許的話,我很想再慢慢修正和補充之前寫的文章😂

我要留言

立即登入留言