2024 DDD 年會筆記

2024 DDD Day


重點 — 2024 DDD Day

DevEx

講者:Ruddy 老師

  • 老師一再強調,很喜歡心流這本書。
  • 開發者體驗度量框架 DevEx
    • 解決開發者工作中的中斷,以度量開發的體驗。
    • 心流(多工分心,開發體驗很差)、回饋和認知負荷(被中斷,開發體驗就不好)
  • 使用者體驗不佳會怎樣?
    • 當改善不佳,會導致開發者體驗不佳,專注在個人項目而已。
    • 當改善不佳,加班、減少參與度、離職率增加。
  • 投資認知,比投資技術更重要:得以看到更長遠的未來,事情的全貌
  • 畫一下自己的職業歷程圖,下一步是什麼? 要走到哪裡?
    • 是自己的事,別人無法幫你做決定。
    • 工作是最容易無法幸福的,難以進入心流。
  • 永遠會有隱性知識。
  • 時間管理的交叉
  • Code Review 是團隊運轉的動力,在專注的空檔去進行

Panel Discussion

討論關於「遺留工作負載」這件事

  • Ruddy:
    • 五千多個資料,不同的版本交雜
  • 陳明正:
    • 不知道(舊的)程式碼要幹嘛,但也不敢刪。
    • 參與過很多重構,結果都…不怎麼理想。
    • 理論上重構是不影響系統的行為,但就…理論上。
  • 麥可
    • 南山人壽:User 有自己的方法,以「他方便」的方式解決問題。
  • Kim:
    • 重構,還是重寫?
    • 問大家的看法? →
      • 陳明正講者:「重構不是解決事情的萬靈丹」
      • 麥可:「重構還重寫,7 ~ 8成 都是寫新的好(重寫)」
      • Ruddy:「重寫一次,要多久時間?」「寫第二次,以為自己很熟,就亂加東西,會死得很難看」「加新的功能,就不是重構」
      • Paul:「重構對這個系統的 ROI (Return on Investment)是如何?」「老闆會問,PM 會問 ROI」「重構的理由: AI 來了,應對奇點的到來」「結合 ESG 和 AI,股價就飛漲!」
      • Ruddy:「82 法則,程式碼也是」「哪些程式碼才是最核心的?」
    • 系統的影響?
      • 陳勉修(?):「怎麼樣做好測試,確保新舊系統是可以正常運行的」
    • 什麼樣的策略,給大家一個視野,在公司中以什麼視角去進行?
      • Paul:「可容錯與不可容錯的地方做切割」
      • Ruddy:「評估團隊成員,有無能力重構?」「先把能力加強(練功),先回頭重構」「嚴格要求不要加功能」「先建立一個平台(類似沙盒環境),把技術結果可視化」「落實經驗編程知識」
      • 陳明正:「有痛點才會想重構」「重構並不容易成功」「重寫式的重構」「寫新的,慢慢遷移到新的」
      • Ruddy:小增量、多迭代。
      • 麥可:「大家都知道重構痛點如何」「Domain Story Telling」「系統流動的是 Value Object」
  • 怎麼了解複雜系統
    • 麥可:「從優先性來了解」
    • Paul :「多管閒事一點,多了解需求面一點」
  • 有沒有「模式」可以聞到 legacy ?
    • Ruddy:「toggle key」「限制理論,找到系統中最大的限制」「跑看板流程,跑一下時間,把流程攤開」
    • Paul:「視覺化,自動化看 commit ,看程式碼的複雜度」

開發者的歹路

講者:陳明正

  • Change Process 循環
    • Request for Change → Impact Analysis → Approve / Deny → …
  • Context 問題
    • PM 不寫文件,覺得太官僚
    • 老闆覺得不要文件
  • commit 訊息
    • 至少要有 What, Why:為何要改,改了什麼?
    • 至少在需求方面,有留下紀錄。
  • 資料庫 Schema 文件補齊
    • 以 Google Sheet 建立 Table Schema Document
    • 自己寫自己的,不要動別人的
    • Schema Review:
      • 有沒有欄位可共用?
      • 沒用的?
      • 可去除重複的?… 等
  • Use case Diagram
    • Arema?
    • 定義:A use case is a sequence of transactions performed by a system that yields
  • 異中求同
    • 共同的部分先呈現出來
    • 不同的先隱藏起來
  • Layering
    • 分層,定義每一層的責任與功能(e.g. Clean Architecture)
    • 定義團隊的 Layering 規則,嚴格遵守(e.g. DDD + Clean Architecture 就算一種)
    • RUT?
  • 重用 Reusability
    • 問題:不知道有什麼 class, method 可以使用,怎麼找「適合」的輪子?
    • 用文件也麻煩,大家也都用 Google 找
    • 解法:
      • 用 LLM 把文件餵進去
      • RAG 的方法,來搜尋

面對 Legacy Code,你有哪些選擇?

講者:Kuma

  • 工商時間:公司 & 台中敏捷社群(可以聯絡 Kuma 🐻)
  • 站起來,問單元測試有沒有做,問到最後只剩 3 個人站著(功能都有做單元測試,而且敢於重構)
  • 拿扣來 demo:
  • 怎麼改? 抽介面
    • 抽一個解決不了,那抽多個就行了。
  • 重構開始:
    1. 先有測試,再來重構,有測試保護才敢於重構。
    2. 測試也是程式,所以也要維護。
    3. 透過測試,教使用者「怎麼用程式」。
    4. 抽介面 → 把各種「身份」+流程,變成 Map → 拿身分的流程做事情
  • 重構兩大時機
    • 寫完功能
    • (有了新功能)修改之前
  • 學了再練,練了撞牆,撞牆再練。
  • *務必用「基本」的測試語法來寫測試。

總結:

  • 這次的重構只是 demo,其實要等「需求來的時候」再來重構,會更好。
  • 面對 Legacy Code 有什麼選擇? 對的時間(重構兩大時機),再做重構。
    • Make the change easy, make the easy change.
    • 看出變化的「脈絡」,再來重構。

領域驅動設計戰術內部物件的協作方式

講者:神 Q 超人

  • DDD 是種「比較抽象高層次」的理解業務的方式。(by 紅皮書)
  • 業務邏輯:在這個領域中,大家是怎麼做、怎麼說的?
  • 用 class (Policy)體現出規則,或者更精準一點,用 class 的名稱「吶喊」出規則。
  • DDD 七龍珠
    • Entity:有 id 存在,代表其獨一無二。(補充:具有生命週期,是個「活體」)
    • 貧血領域模型:只有 getter, setter ,沒有辦法「體現」物件在領域中的作用。(e.g. 我只知道,可以 setName,但只知道該物件有個 field 可以塞這個值,不知道是「使用者可以改名」這個行為)
    • VO:不需要辨識物件的 id ,值一樣,就一樣。
    • Aggregate 一整包的 Entity…
    • Domain Event:領域事件。
    • Factory:工廠模式。可以應用在 Aggregate 身上,用來建立該 Aggregate 底下的 Entity。
    • Repository:資料持久化。
  • 協作
    • Clean Architecture
    • demo 程式碼
      • mapper → Repo 變成 entity → service → view model
      • entity → Repo → mapper
  • *個人認為:視角的轉換,領域中代表就不一樣
    • $1000 元拿來購物,就只是 VO,張張等值且被視為相同。
    • $1000 元拿來驗鈔,會是 Entity,會拿序號來比對,張張等值但不相同。先找出「疑似假鈔」的真鈔,此時該 $1000 就不再是 VO,因為與其他鈔票不相同,已具有「識別 id」。
  • REF

From EventStorming to Event Store passing through BDD

講者:Alberto Acerbis

  • Event Storming?
    • Why? 尋求共識,找出共通語言
    • What?
      • Big Picture:大白板,大家在上面討論各自對於領域的「想像」
      • 「過程」建模:大家要知道在這個地方,流程與工作流是怎麼一回事。
      • Software Design:
        • 有了「共通語言」,大家才知道各自要做的事情是「哪一件事」
        • 透過大家(工程師們)討論的過程,討論出軟體設計的共識,特別是 Command / Action 的共識。
    • 聚焦在:command / action, event 和 aggregate。
  • Event Sourcing
    • 事件溯源:每一項事件都存起來,就知道用戶做了什麼事。(聽不懂講者講的,這是我自己補充的)
    • EventStoreDB:實作 Event Sourcing 的開源 DB
    • CQS:指令和查詢隔離
  • Event 互動 Big Picture
    • Domain Event:在 Bounded Context 自己人溝通,所以說,不要「直接 publish」出 bounded-context 出去給外界。
    • 共通語言:用「一樣的字」,確保同一件事,是用同個字來表達。(*以我們的產品來說,Match 和 Contest 就是很重要的 Ubiquitous Language,而在中文都可以翻譯成「比賽」,很容易搞混)
  • 在「單片模式的解決方案」把 bounded context 確實拆開的話…
    • 就可以很容易地把邊界內的服務,部署成「微服務」。
  • Command Event
    • 需要是「immutable」的,確保外界只能「讀取」使用
    • 接受到事件(觸發行為),物件經過驗證這個事件「確認沒問題」之後,
  • 總結:BDD
    • Given, When and Then
    • 當在什麼情境(可能是在某 Bounded Context 下,在物件的 OOO 的狀態下),做了什麼(Command),就要有(東西)去做事情(收到事件後去做事)
    • Sample
      • Given:釀酒廠酒量低 → 發送:釀酒事件 → 接著:釀酒
      • Given:釀酒廠酒量足夠 → 發送:釀酒事件 → 接著:不做事

心得

關於演講的反思

  • 有互動會很活潑,自己不尷尬,尷尬的就是別人。
  • 有送書就很踴躍。
  • 聽不懂沒關係,筆記寫起來,以後再回來看,可能就懂了。

志工心得

第一次擔任活動志工,沒有想像中那麼困難。可能是因為組長已經分配好工作,我們(小弟們)只要接指令,在指定時間做好任務就好。

身為「議程組」的志工,其實不用做什麼太困難的事,只要做:

  • 活動前發 Email 告知講者要參加
  • 在活動開始的前一週內,與國外遠端的講者,確認網路連線與影音是否足夠清楚。
  • 活動途中,常駐於負責的講堂。講座開始前,確認講者到場;接著是負責講座的開場與結尾。

志工團隊的大家,人都蠻 nice 的,許多都是在 DDD 領域頗有經驗的開發者。看到前輩們可以在講座上與講者侃侃而談,倍感佩服。心想這就是開發經驗與人生經驗的差距,許多方面「無關技術」,而是經過時間磨練而來的「體悟」。(尤其今年 DDD 是以「遺留系統」作為主題,他們碰過的技術債,可能比我吃過的飯還多。)


REF

  • 20240913 DDD 年會