2023 DDD年會 簡單回顧

DDD 啟發


重點 — 搞清楚業務在幹嘛再動手

  • 心智圖

    Untitled

動手再動口 — 先寫好再重構

講者們提到的概念雖然不盡相同,但都有一個共識,就是重構是為了讓程式碼「變得更好」。

那如果連功能都還沒有完成,就先做「瞎猜」重構,這時根本沒有所謂的「更好」,因此不是個重構的好時機。畢竟連個影都沒有,哪來的「比較級」可言?

以前我就會這樣做,在程式都還沒確認對不對之前,就先把腦中浮現的pattern拿來套(可得性偏誤!),雖然基於經驗來看,這樣做沒什麼不對,但就會失去了其他更好解法的可能性,相當可惜。

所以說,先寫好功能,以測試來驗證行為是否正確,接著再來重構,把程式碼「分門別類」整理好。話說回來,這次聽到重構相關的,有幾個概念想要分享給大家:

  1. 分組: 將相同的系統 or 層級 or 功能類似的,放在一起,將其適當地「耦合」在一塊。
  2. 什麼是更重要的? 一邊重構時,一邊問自己,什麼是這個系統,或是目前這個scope比較重要的功能? 畢竟時間有限,重構也看重「CP值」,越「高階」的概念,優先度越高。
  3. 什麼時候不該重構? 因為重構是把「既有」的程式碼搬來搬去,做點修修改改,那如果碰到的是一個老摳摳系統(legacy system),初步看下來,是坨難以理解、無可理喻、束手無策的程式碼,就要先停下來,想想是不是「重做」比較快了。

Event,到處都是Event

Untitled

首先是Event Sourcing,聽了兩場演講分享後,總算才有比較明確的概念。

簡單來說,就是個別於以往Current State Sourcing,只存「當下」的資料,像是我們只會存最後一筆使用者改過的暱稱,沒有把之前改過的紀錄都存起來;而Event Sourcing以Action為單位,將每筆操作紀錄都存起來,使用者改了哪些暱稱,都可以一一查出來。

那你會想說,存這麼多資料幹嘛? 使用Event Sourcing的最大好處,是可以知道事件的數量,以及事件的「歷程」,而且既然有了這麼多的事件,可以透過這些重要資料,從中洞察轉換率的優化調整(像是發現到使用者加入購物車之後,就沒有然後了…)。

接著是Event Storming,這解釋起來,大家可能就比較沒那麼陌生。

Untitled

翻成中文是「事件風暴」,是頭腦風暴「Brain Storming」的一種變體,是一群人聚在一起,一起發想「當下目標範圍」的整個事件流程。

比方說,今天的目標是「獎勵任務系統」,使用者可以透過解任務,獲得各種獎勵…(下略。大家就要把想到的事件,一個一張「便利貼」,貼到白板上,並把流程整個串起來。

一次為時約0.5hr~1.5hr,現在常用Miro這個「線上白板」工具來做Event Storming,好處是方便編輯查找,在storming之後可以隨時補充細節。

概念滿天飛

以下是我在講座聽到的一些概念,僅有草草的筆記與條列,做個簡單的紀錄 :)

  • Coupling的程度怎麼評估? — Learn Domain Driven Design的作者 以三個維度來綜合評估耦合度: Strength, Distance, Volatility

    • Strength:假設有兩個組件(不管組件是啥),組件之間以「關聯與互相認識」在連接著;共享的「知識」(商業邏輯之類的),其強度越高。
    • Distance:離細節越遠,距離越長。距離越遠的更改,其代價(cost)越大。
    • Volatility:波動度,也就是更改的影響程度。通常越核心的功能,其更改的波動度也越大。
    • 總結: 程式更改的Pain = Cost Coupling = Strength * Volatility * Distance
      • 只要其中一項是零,Pain就是0,試著決定「哪一項降低為0」
      • 盡量降低整合的 strength(as much as possible)
      • 如果strength和volatility很高,就降低distance
  • CQRS — 讀取和寫入分開的策略。

    • Command和Query分開,讀寫分離
    • 變成讀和寫各別是「單一職責」
    • 讀和寫個別優化
  • Domain — 領域,核心要關注的東西。 以故事來說的話…

    • Entity: 實體,故事的主角。
    • Domain Event: 事件,說說Entity做了哪些事。
    • ValueObject: 價值物件,形容Entity的狀態。
    • Service: 服務,負責說故事的。
  • SOLID — 真的懂了嗎?

    • 是一個降低程式依賴,減少未來改變衝擊(降低風險)的原則。
    • 原則懂了,才知道何時可以違背。
    • 先寫醜的(TDD驗證) → 重構 → 想辦法SOLID化。
    • 過早作抽象,會把「應該或不應該」的邏輯做整理,之後維護就會相對困難。
  • 概念到產出的「雙菱形模型」 或稱雙鑽石設計流程

    Untitled

    • 從需求定義到產出,是個發散 → 收斂的循環
    • 左半邊是「問題」,右半邊是「解決」
    • 通常程式人員關注的正是右半邊,但其實,現在開發前期的問題定義階段,開發人員通常也要參與(看看Event Storming)。
  • 範疇論 是數學的一門學科,是關於及其關係的一般理論,以抽象的方法處理數學概念,將這些概念形式化成一組組的「物件」及「態射」。 by 維基百科

    • 通常一段描述中的「名詞」就很有可能是實體(Entity)。
    • 只有實體才需要被追蹤(主角!)。
    • VO(Value Object)只是一個實體的「狀態」
  • Domain 的 Storytelling流程敘事法 圖片僅供示意

    Untitled

    • Scenario based(場景為基礎)
      • 一張表,一個故事
      • 描述有關Actor和Activities的互動
    • 不是一個「一體適用」的工具
      • 故事會有好幾個「層級」的細節。
      • 會需要一層一層剝開,有粗粒度和細粒度的不同故事。

總結

真正厲害的,是說個信服人的好故事,不是寫出驚天駭俗的程式。

聽君一席話,勝讀十年書。這兩天聽下來,雖說沒有打通人督二脈這麼厲害(也沒這麼好用的好嗎…),但至少聽到的概念林林總總,足以勝過我自己辛苦東拼西湊的各種資訊。

在經過「資訊洗禮」之後,發現自身的渺小與不足,寫好程式、讀懂代碼,只不過是基本中的基本而已。不說這麼多了,還有「DDD藍皮書」等著我去啃呢 😃。

總會有一個比自己更強大的存在,就是「時代」。 — 底層邏輯


REF