2024 DDD 年會筆記
2024 DDD Day
2024/10/19
重點 — 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:
- https://gist.github.com/kuma-cloud-latitude/c159c671e594bc4f1c144eb41563ea9a
- 問大家哪裡有問題
- 每多一個就要改 Code
- 重複的 Code
- 單一職責、開放封閉
- 問「開放封閉」:新功能,只要「新增」就好,不用改 Code
- 怎麼改? 抽介面
- 抽一個解決不了,那抽多個就行了。
- 重構開始:
- 先有測試,再來重構,有測試保護才敢於重構。
- 測試也是程式,所以也要維護。
- 透過測試,教使用者「怎麼用程式」。
- 抽介面 → 把各種「身份」+流程,變成 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 年會