iT邦幫忙

2021 iThome 鐵人賽

2
Software Development

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

Day 31: 【全系列終】架構考古學

Appendix: 架構考古學

聯盟會計系統

  • 簡述
    1960 年代,很簡單的 CRUD 記帳系統,由電晶體 & 部分真空管所組成的超大電腦 (GE datanet 30),需自幹 OS & Driver
    https://ithelp.ithome.com.tw/upload/images/20211017/201386436T8EdLVeeH.png
  • KeyWords: Overlay System, Preemptively Swap, Supervisor, Interrupt
  • 小結
    • 劃分 I/O 、儲存裝置、與主系統的 「邊界」
    • 盡量將依賴反向,使依賴關係和控制流的方向不一致

筆者讀完這節腦中馬上浮現以前在恐龍本(作業系統)上看到的種種 Virtual Memory, Scheduler 相關概念... 不得不佩服原作者在那個年代竟然能自行領悟出這些東西... (跪)


雷射修阻

  • 簡述
    在 M365 Computer 上開發的小型作業系統,為了雷射修阻及其相關應用程式所開發
  • KeyWords: Bootstrap Program, Master Operating Program (MOP), Isolation Layer, Data-Driven Language (DSL)
  • 小結
    • 沒有強制劃分開系統程式碼和 DSL 編寫的應用程式之間的邊界。耦合處處可見 (再一次強調解耦的重要)

4-TEL

  • 簡述
    每天晚上自動測試電話線路,並為所有需維修線路產生報告的晶片系統 (Firmware?)
  • KeyWords: 向量化、物件導向原則、UI & 業務規則分離、多型分派 (Polymorphic Dispatch)
  • 小結
    • 本章作者遇到一個痛點:每一次修正系統內的任何指令碼,都需要重新更換全部 30 顆晶片 (成本極高)
    • 於是花一段時間想出「向量化」解決方案 (即,將程式劃分為 32 個可獨立編譯的原始檔、並做動態定址)
    • Plugin 架構:讓晶片可獨立部署 (Independently Deployable)、引入物件 (Objects) 的概念

服務區域的電腦

  • 簡述
    • 修理工派遣系統 (承上一個專案)
  • KeyWords: Multiprocessing, Context Switch, Locks, Semaphores, Race Conditions, Clean Code
  • 小結

    「派遣決定的程式碼是由非常聰明的人設計及編寫的,但他卻不是一位善於溝通者。編寫程式碼的過程是被這樣描述的:『盯著天花板看三個星期,然後有兩天程式碼就從他身體的每個洞湧出來了 - 然後他就辭職了』」

    沒有人理解這個程式碼。最後,我們的管理階層告訴我們,要鎖住這些程式碼並且永遠不要修改它。程式碼被正式宣告僵化了」

    「這次經驗帶給我的是,良好、整潔的程式碼的價值


插曲: 學習「新」語言 — 「C」

「在 8085 Assembler 中寫 Code 可一點都不好玩。我聽說有一種在貝爾實驗室大量使用的『新』語言。他們稱它為『C』。我對這種語言的簡單優雅感到震驚,它沒有犧牲組合語言的能力,並使用更方便的語法來提供同等的能力。我變心了」

「現在唯一的問題是,面對一群組合語言程式設計師,如何說服他們應該使用 C 語言。但這是另一個噩夢般的故事......」


Basic Operating System and Scheduler (BOSS)

  • 簡述
    • 作者用 C & Assembly 在 8085 平台上寫出的任務切換器
  • KeyWords: Concurrent Tasks、Non-preemptive、Blocked、輪詢 (Polling)
  • 小結
    • 該軟體成為未來幾年大量專案的基礎

DLU/DRU

  • 簡述
    • 加入遠端連線功能的派遣系統,因應公司規模的擴張
    • DLU 的架構設計是基於資料流模型的
      每個任務都只專注在一個小工作,並透過一個佇列 (Queue) 將它傳遞給下一個任務。類似工廠的組裝流水線 (Pipeline)
    • DRU 的架構設計則完全相反
      為每個終端機建立一個任務,沒有 Queue、沒有資料流。可類比成許多建造者,而每一個人都建造一個完整產品
  • 小結

    「當時我認為我的架構很優秀。當然,MIKE 認為他的比較好。當然最後,兩個人都工作得很好。我意識到,軟體架構可以大不相同但同樣能發揮作用


Voice Response System (VRS)

  • 簡述
    • 加入按鍵語音功能的故障定位系統
    • 採用了當時很潮的「新技術」:嵌入式 SQL (Embedded SQL)
      導致 Code 和 DB 操作密切耦合
    • 團隊決定更換資料庫供應商 (UNIFY --> SyBase)
      經過三個月的努力,決定放棄 (成本極高)。最後只能聘請第三方維護 UNIFY

      「當然,維護頻率逐年上升」

  • 小結

    「這是我了解到『資料庫』是該與『系統的整體業務目的』隔離的原因之一,也是我不喜歡強烈耦合到第三方軟體系統的原因之一」


The Electronic Receptionist (ER)

  • 簡述
    • 有史以來第一個語音郵件系統

      註: 我們的雇聘合約清楚表示,我們發明的任何東西都屬於公司。我的老闆告訴我:「你用一美元把它賣給了我」

    • 這個系統的架構如果在今天會被稱之為以服務為導向的 (Service-Oriented)
    • 這款產品的市場行銷並不理想。Teradyne 是一家銷售「測試設備」的公司,而他們不了解如何打入「辦公設備」的市場。經過兩年的嘗試,CEO 決定放棄

修復工派遣系統 (Craft Dispatch System)

  • 簡述
    • 管理電話維修人員的系統
    • 在搭飛機時,作者發明了一個名為 Field Labled Data (FLD) 的方案,類似現在的 XML 或 JSON
    • 作者開始建立現在稱之為微服務架構 的東西
      使用 XML 透過共享記憶體模擬通訊協定的微服務通訊 (1985 年)
  • 小結

    太陽底下沒有新鮮事


Clear Communications

  • 簡述
    • 1988 年,作者與原同事們離開了公司,成立的新創公司

    「這是一間新創公司,我們每週工作 70 到 80 個小時。我們有願景。我們有動力。我們有意願。我們有能力。我們有專業知識。我們擁有股權。我們夢想成為百萬富翁。我們有夠荒謬」

    「所以我們寫程式。寫程式。寫程式。但三年後,我們沒能做到的是賣出產品。市場對於我們的宏偉願景並不特別感興趣」

  • 小結
    • 沒有結論。最後作者接到獵人頭電話,被挖去大神 Grady Booch 的矽谷公司了

正好筆者學生時期有過幾次參與創業團隊的相關經驗,實驗室也曾與國內某量化交易新創公司密切合作過一小段時間。筆者看完這一節饒是特別有感觸。也許正因為荒謬,所以才叫青春吧 (笑)


插曲: "Uncle Bob" 的由來

新創公司裡有一名年輕研究員,給每個人都取了綽號。於是作者成為了 Uncle Bob

「最終,我意識到這是一個非常好的品牌」

插曲: 網路辯論

「當我學習時,也開始在 Netnews 上進行辯論。正是在這些辯論中,奠定了 SOLID 原則的基礎。所有的辯論,甚至是某種意義上的,都引起了我的注意......」

最後,作者"疑似"因為在 Netnews 上的發言而被獵人頭挖角

「熱血充滿了我的臉。我知道這代表什麼。這是 Grady Booch 的公司。在我面前,我看到了與 Grady Booch 合作的機會!」


ROSE

  • 簡述
    • ROSE 是一個巨大的 C++ 程式。由層 (Layers) 組成
  • 檢討
    • 沒有將依賴性指向高層級的策略
    • 沒有建立一個真正的 Plugin 架構
    • 採用了「物件導向資料庫」

      「但我們得到的是一個巨大的、緩慢的、侵入性的、昂貴的第三方框架。使我們的生活如同地獄一般」

  • 小結

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

    「所以我了解到,偉大的架構有時會導致嚴重的失敗。架構必須足夠靈活以適應問題的規模」

P.S. 以中文來說,過度設計 (Over Design) 會有比較多的相關文章出現


建築師登記測驗

  • 簡述
    • 1990 年代初期,作者已創業成為顧問,教導人們導入物件導向設計和架構
    • 第一個客戶:Educational Testing Service (ETS)
    • ETS 已將問題分解成 18 個獨立的測驗,用於建築師候選人的測驗
      每一個測驗都需要 1 個 GUI 程式及 1 個評分程式
    • 作者嘗試一次為 36 個程式開發一個可複用框架
      於是和搭檔兩人花了一年開發出 45,000 行的框架程式碼
  • 問題
    • 發現框架並不是特別可重用,有一些細微的摩擦,所以沒辦法發揮作用...
    • 計畫表拖延了將近一年的時間
  • 小結
    • 於是作者重新開始,把舊框架放在一旁,開始同時寫 4 個新的小測驗,交付後再接著開發 4 支測驗

    「我們學到了一個很好的教訓:在第一次創造可重用的框架之前,你無法創造可重用的框架。要把它與幾個可重用的應用程式一起建置」


全書完

「我希望的是,你會喜歡我在回憶之路上這次小小的旅行;並且一路上你可以學到一些東西」

「當然,這只是部分歷史。我還經歷了許多其他的專案。而我有意地將歷史停止在1990年代初期 - 因為我還有另外一本書是用來描述1990年代後期的事件...」

取自: Clean Architecture (p.305)

P.S. 讀者們是否注意到,本書幾乎都沒有提到 「敏捷 (Agile)」 這個關鍵字? 有興趣的可自行參見 Robert C. Martin 的另一本書: 「無瑕的程式碼 敏捷完整篇:物件導向原則、設計模式與C#實踐」


Reference

  1. Clean Architecture: A Craftsman's Guide to Software Structure and Design
    尋找圖片不小心查到的原文書...

後記

非常感謝各位讀者追蹤到此,這是我第一次參加鐵人賽,也是第一次嘗試在網路上將自己的心得整理成文章發表。真的從中獲益良多...

這 30 天裡,利用下班之餘,讀了近 800 頁的內容。好幾次加班回家後都只想躺平,但還是決定拿起書來翻閱,一邊 Google 查閱補充資料。讀完 Clean Code & Architecture 後,上班時間看著公司專案,慢慢地能理解那些以前似懂非懂的架構,甚至開始能從中嗅到程式碼的氣味 (Code Smell)、對於如何重構那些 "Legacy Code" 也開始有了點想法...

最大的感動大概就如鐵人宣言裡所述 「原來,我做得到」

有一點還是對讀者感到很抱歉,到開賽的第二周以後其實文章的完成度就普遍下降很多,甚至到後期常常只有大小標題 + 引言而已。我不選擇把各章節拆散到每一天、也不過度簡化書中內容 (甚至會補充點圖片或 Keywords),只希望能盡可能地將 Clean 系列書所提及的理念推廣給各位讀者們

接下來我預計會再花 30 天把未寫完的內容補齊


上一篇
Day 30: 遺漏的章節
系列文
成為乾淨的開發者吧! Clean Code, Clean Coder, Clean Architecture 導讀之旅31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
claire01125
iT邦新手 5 級 ‧ 2021-10-20 09:50:31

終於可以留言了! 太棒的分享了,期待你完成整個系列!!

JC iT邦新手 3 級 ‧ 2021-10-20 23:30:36 檢舉

謝謝 > < 目前補到 Day 03: 命名~

我要留言

立即登入留言