通過語言的比喻句發現隱藏的DDD模型 - verraes

banq發表於2021-12-21

這是DDD專家 Mathias VerraesRebecca Wirfs-Brock最新文章,他們擅長從人類通用語言中發現模型,這是不同於事件建模和事件風暴的第三種DDD建模方法,也是比較更接近DDD原著的含義。

該文講述瞭如何在一堆資料分析技術人員當中引入建模會議,通過參會者的語言溝通,發現了複雜系統中湧現的一種現象,人們不知道它叫什麼情況下,一般是使用類比和比喻修辭語句形容它,這是一種隱喻用法,是發揮想象力以後的直覺判斷,如水花這個詞語就是用來比喻河流在流動過程終湧現的一種現象,如同植物花朵一樣。兩位專家在支付版權費領域中發現了他們忽視的Trust信任模型,這個模型並不存在實際領域中,但是人們在構建這個領域的軟體系統時,卻湧現出一種渴望,需要一種模型來作為索賠的前提條件,客戶信任度為零與滿分決定了後面不同的支付流程。

原文大意如下,點選標題見原文:

Mathias 為一位客戶提供諮詢,客戶是一位經紀人:負責向版權所有者支付使用他們內容的費用。為此,他們弄清楚了作品的版權所有者是誰。然後他們跟蹤使用索賠或支付,計算欠款,收款並付款。瞭解誰擁有什麼是他們業務中最棘手的部分之一。

——“這只是一個技術問題。”

——“但沒有人真正瞭解它是如何運作的!”

— “我們中的一些人瞭解其中的大部分內容。這恰好是一個複雜的問題。”

——“無論如何,讓我們做一點建模吧。”

幾周後,我們有了一個豐富的模型。它有清晰的概念,並且更容易理解。業務利益相關者開始關注,並積極參與建模。他們看到了偉大的想法,可以描述他們想要什麼。事情是這樣發生的。

 

案例分析

確定版權所有權(DDD核心子域)是一個複雜的資料匹配過程,它從多個資料來源中提取資料:

  • 公司自行研究
  • 離岸資料清洗
  • 來自維基風格來源的公開資料
  • 公開可用的精選資料
  • 私人資源,公司為此支付了許可費
  • 個人直接提交
  • 代表版權持有人的機構

該公司存在資料質量問題。由於資料來源的多樣性,任何說法都沒有單一的真實來源。資料往往不完整和不一致。最重要的是,存在欺詐的可能性:不良行為者聲稱擁有作者作品的所有權。

大多數人都是出於善意行事。即便如此,資料總是會很亂,整理起來也需要付出相當大的努力。資料在不斷變化:即使作品的所有權很少發生變化,資料卻發生了變化。

 

資料匹配

工程師們一直在改進“資料匹配”。這就是他們所說的協調不一致的過程,並就誰擁有什麼以及誰必須向誰支付費用提供清晰的決策。

他們使用了 EventSourcing,並且可以輕鬆地根據歷史資料重放新的匹配演算法。資料匹配演算法在不同資料來源中匹配相同作品的相似宣告。當多個資料來源同時發生時,匹配成功。

但是有時匹配很差:一個作品的50% 的來源指向一個所有者,50% 指向另一個所有者,僅根據這些資訊,無法確定這個作品的版權所有者是誰。但是通過使用歷史資料,該演算法可以更頻繁地找出哪些來源是成功匹配的一部分。他們可以賦予這些來源更多的權重,並朝一個方向或另一個方向傾斜。這樣,即使 50% 的訊息來源聲稱 A 為所有者,50% 的訊息來源聲稱為 B,也可以找到答案。

 

領域建模

程式碼的職責是:提取資料、過濾、重新格式化、解釋和應用匹配規則。

所有的情況和規則使資料匹配變得非常複雜。只有少數工程師知道它是如何工作的。Mathias 注意到工程師無法解釋它是如何工作得很好。與他交談的業務人員根本無法解釋有關該系統如何工作的任何內容。他們簡單地將其稱為“資料匹配”。團隊並不關心這個。在他們眼裡,複雜不過是他們不得不面對的事情。

Mathias 提議召開白板建模會議。最初,工程師們反對。畢竟,他們不覺得這是一個業務領域,只是一個純粹的技術問題。然而,Mathias 認為,結果的質量決定了誰得到了多少報酬,而錯誤意味著客戶最終會轉向競爭對手。因此,即使資料匹配是技術性的,它在核心域中也發揮了重要作用。關於它的知識是粗略的,工程無法解釋它,商業不理解它。正因為如此,他們很少討論它,當他們討論的時候,它是純粹的技術術語。如果溝通很困難,如果對話很麻煩,你就缺乏一個好的共享模式。

通過建模,匹配過程對工程師來說變得不那麼不透明瞭。我們對提取資料、處理資料、識別匹配和做出決定的不同步驟進行了更清晰的區分。該模型包括來源、索賠、對賬、例外情況。我們也在白板上繪製了匹配規則,使這些規則在模型中明確一流的概念。隨著匹配過程變得更加清晰,導致系統設計的基本思想開始浮出水面。從“是什麼”,我們轉向“為什麼”。這使我們處於開始發現抽象的有利位置。

 

Trust模型

漸漸地,他們構建演算法的假設前提(根據)在對話中浮出水面:

我們陳述了這些假設,將它們寫在便籤上,然後放在白板上。一個公認的假設是,當資料來源經常與其他來源一致時,將來出錯的可能性較小。如果一個來源更可靠,它應該更受信任,因此來自該來源的宣告在誰擁有所有權的決定中具有更大的權重。

在進行領域發現和建模時,觀察並傾聽語言中的微妙之處是很好的。在這些對話中,非正式地使用了諸如“可靠”、“信任”、“增加權重”和“決策”等詞。

在這些情況下有效的是對語言有一種健康的痴迷。

將此語言新增到白板。

提問:這個詞是什麼意思?

通過這些討論,“信任Truts”的概念變得越來越重要。它在白板模型中變得明確。

它是有形的:你可以看到它,指向它,移動它。你可以開始講關於信任的故事。為什麼一個來源會更受信任?什麼會破壞這種信任?我們可以發現哪些邊緣情況會以不同的方式影響信任?

  

Trust為物件

在下一次建模會議中,我們談論了很多信任。從人們隨意加入談話的一個詞,它已經演變成一個有意義的詞。Mathias 提出了一個小小的思想實驗:如果Trust是程式碼中的一個實際物件會怎樣?那會是什麼樣子?很快,一個簡單的信任模型出現了。

信任是一個值物件,它的值代表我們對資料來源的信任“數量”,或者我們對作品或使用的主張的信任,或者我們對提出主張的人的信任:

信任度的衡量標準為 -5 到 5。

該數字決定了版權支付是否獲得批准,是否需要其他來源來確認,或者公司是否需要做進一步的研究。

這是一個重大的思想轉變。

Trust模型為我們提供了一種新的方式來思考我們的核心領域:根據誰最能贏得我們的信任就向其付款。

從白板概念轉變為使信任Trust成為設計中的基本元素。該團隊清理了分佈在資料匹配程式碼中的臨時邏輯,並將其替換為單個信任概念。

舊程式碼也會動態計算相似的值以確定“匹配”。這些計算在程式碼中傳播和複製,隱藏在許多分支中。團隊沒有看到所有這些值和計算實際上是同一基本概念內幾個方面。他們沒有看到可以共享計算,無論您是匹配來源、人員還是宣告,沒有共享的抽象。

  

信任Trust是一個流程

團隊正在設計一個 EventSourced 系統,因此很自然地,話題轉向了哪些事件會影響 Trust。

信任如何隨時間演變?

過去在舊模型中匹配的索賠或支付,現在變成了對我們的索賠信任產生的積極或消極影響的事件。

贏得信任(或失去信任)現在被認為是一個流程。

新的索賠動作是該流程中的一個事件。信任Trust現在被視為信任收益流程的快照。

如果索賠被拒絕,但出現了新的證據,則信任度增加並且索賠獲得批准。

某些來源,例如公司為其購買許可證的私人資料庫,高度可信且穩定。對於其他人,比如人們可以提交宣告的 wiki 風格的資源,信任更加不穩定。

 

業務參與

在討論新的信任Trust模型和信任建立概念期間,團隊定期返回業務以確保這些概念有效。他們詢問了他們應該如何分配信任以及他們應該使用什麼標準的見解。我們看到了一個有趣的效果:企業中的人們投入到這些對話中並加入了建模會議:

資料匹配從對話中消失了,Trust 接管了。

人們普遍對能夠分配和發展信任感到興奮。工程師的新模型成為企業內部的共享模型。

 

信任是一種算術

版權經紀領域專家開始向團隊丟擲場景:如果信任度為 0 的來源 A 提出的宣告得到信任度為 5 的來源 B 的證實,該怎麼辦?

宣告本身現在受到高度信任,但對來源 A 的影響是什麼?一隻燕子不會造就春天,因此源 A 肯定不應該被授予與源 B 相同級別的信任。

另一方面,確認信任的重複模式應該反映對源 A 的更高信任。

在這些持續探索中,業務和工程人員列出了不同事件如何影響信任的規則,並對其進行了編碼。

通過檢視程式碼中的規則,出現了一個新想法:

信任Trust可以有自己的演算法:一組定義信任如何積累的規則。

例如,信託為 3 的索賠現在被信託為 5 的索賠所證實,現在將被分配一個新的信託 4。更大的算術集解決了證實索賠的索賠的各種排列,來源證實了來源,以及隨著時間的推移證實的模式。

Trust 物件封裝了這個演算法,併為其管理屬性和行為。

從一個貧血的 Trust 物件,我們現在得到了負責所有這些操作的更豐富的 充血Trust 模型。該團隊提出了多型 Strategy 物件。這些使他們能夠更換不同的機制來分配和發展信任。舊的資料匹配程式碼將獲取和儲存資訊與龐大的邏輯混合在一起。現在,該團隊發現很容易將其分成一個處理管道的層,與乾淨的 Trust 模型分開。

 

模型的演變

總之,下面這是演變:

  1. 計算匹配值的臨時程式碼。
  2. 在解釋當前系統如何工作的對話中使用信任。
  3. 信任作為程式碼中的值物件。
  4. 將信任作為一個流程,通過分配新信任值的事件(例如找到匹配的宣告)來發展信任。
  5. 信任作為業務和工程之間的共享術語,取代了技術資料匹配的舊語言。
  6. 探索如何使用更真實的場景分配信任。
  7. 構建控制信任計算的演算法。
  8. 分配信任的多型策略。

當您找到更好、更有意義的抽象時,它就會成為催化劑:它支援其他建模結構,允許圍繞該概念形成其他想法。這需要探索、編碼、對話、嘗試場景,......沒有實現這一目標的黃金祕訣。你需要對可能性持開放態度,並花時間去做。

 

好的比喻

我們從原始程式碼轉變為基於信任新概念的模型。但是這個Trust這個概念是什麼東西呢?信任是一個比喻。1真正的信任是人類的情感,部分是非理性的。您本能地信任某人,並且出於可能會改變的完全主觀的原因。機器沒有這些情緒。我們的系統中有一個人工指標,有演算法來操縱它,我們將其命名為 Trust。這是一個代理詞。

這個比喻可以實現更緊湊的對話,工程師和領域專家都可以討論信任,而不會在技術細節上彼此迷失,這一事實證明了這一點。“這個訊息來源的說法得到了其他訊息來源的反覆證實”這樣的句子被替換為“這個訊息來源已經建立了信任”,所有人都知道這意味著什麼。

這個比喻允許我們處理相同程度的複雜性,但我們可以推理確定信任,而無需瞭解使用它的每個細節。對於我們這些沒有愛因斯坦大腦的人來說,現在處理程式碼要容易得多,它降低了認知負擔。

在正確的上下文中使用一個好的比喻,例如信任,使我們能夠實現以前無法輕鬆完成的事情。該團隊重新考慮了一項功能,該功能允許他們更換不同的策略來匹配宣告。最初他們駁回了這個想法,因為在舊程式碼中,構建成本高得令人望而卻步。這將導致巨大的條件樹和對共享狀態的龐大依賴。他們必須非常小心,而且很難測試這種邏輯。使用新模型,換出多型 Strategy 物件是微不足道的。新模型允許測試像信任物件這樣的低階單元、像信任建立過程這樣的高階邏輯和單獨的索賠策略,每個測試都保留在一個抽象級別。

我們的 Trust 模型不僅可以更好地組織細節,而且還簡潔明瞭。我們可以轉到程式碼中的一個點,並知道某些事情是如何確定的。Trust 物件在程式碼的一個地方計算它自己的值。我們不必檢視程式碼中的 20 個不同條件來理解行為;相反,我們可以檢視單一策略。發現錯誤要容易得多,這反過來又有助於我們使程式碼更正確。

一個好的模型可以幫助您推理系統的行為。一個好的比喻可以幫助您推理系統所需的行為。

信任的比喻開啟瞭解決複雜性的途徑。我們通過仔細聆聽用於描述解決方案的語言,在示例中使用該語言並嘗試思想實驗來發現它。我們不再匹配資料,我們正在確定信任並使用它來解決索賠。我們現在沒有對規則進行編碼,而是對它們進行編碼。因此,我們是更好的版權經紀人。

 

不好的比喻

警惕糟糕的、不恰當的比喻。想象一下,該團隊以“星級”作為隱喻。當然,它也可以用作量化,但它基於流行度,並計算平均值。我們仍然可以構建與 Trust 模型相同的所有行為,但有很多奇怪的規則,例如“我們自己的來源獲得 20 個五星級評級”。當您注意到必須將問題空間的元素強加到隱喻中,並且您想說的內容與該隱喻允許您說的內容之間存在摩擦時,您需要擺脫它。沒有一個比喻能完美契合,但一個糟糕的比喻會讓你陷入尷尬的對話,而不會讓你明白。

更棘手的是,每當你引入一個新的比喻時,一開始可能會很尷尬。在我們的案例研究中,信任並沒有立即成為一個被充分探索和接受的比喻。在採用一個新的好比喻的早期鬥爭和一個根本不好的比喻之間有一條微妙的界限。繼續嘗試,努力使用你的新比喻,看看它是否能給你帶來解釋力,如果沒有,不要害怕放棄它。

有時,根本沒有任何好的比喻,甚至找不到更簡單的模型。在這些情況下,你只需要處理它。沒有找到任何簡化。您只需要制定所有規則,列出所有案例,並按原樣處理複雜性。

 

結論

為了找到好的隱喻,把自己放在一個你會在談話中注意到它們的位置。邀請不同的角色參與您的設計討論。對語言有一種健康的痴迷:這是什麼意思?這是最好的表達方式嗎?觀察這種語言,聽聽人們隨意說的術語。捕捉人們使用的任何隱喻。在談話中加強他們,但如果你覺得你有足夠的力量,準備好放棄他們。隱喻能帶來清晰嗎?它是否有助於您更好地表達問題?嘗試場景和邊緣情況,即使它們極不可能。他們會教你隱喻的侷限性。然後提煉比喻,同意一個確切的意思。在您的模型中使用它,然後將其轉換為您的程式碼和測試。隱喻是語言的運作方式,我們的大腦如何賦予意義,

Mathias VerraesRebecca Wirfs-Brock撰寫。原文擊標題

相關文章