l

2021年1月21日 星期四

愛上Mob Programming(上)

Jan. 21 01:08~14:24

▲ezKanban團隊mobbing實況


緣起

約略四年多前Teddy聽指導教授鄭老師提到實驗室開始全面採用mob programming(簡稱mobbing,這是Teddy第一次聽到這個名詞。

如果鄉民們把mob programming丟到Google翻譯,會得到暴民編程的中文解釋,因為mob的英文就是暴民的意思。最近很流行的新聞—美國擁護川普的群眾衝入國會大廈,英語新聞就用mob來指稱這群人。

***

當然mob programming絕對不會是找一群暴民來寫程式,根據維基百科的解釋:

(譯自英文) Mob編程是一種軟件開發方法,其中整個團隊在同一時間,同一空間和同一台計算機上處理同一件事。這類似於結對編程,在結對編程中,兩個人坐在同一台計算機上,並同時在同一代碼上進行協作。通過mob編程,可以將協作擴展到團隊中的每個人,同時仍然使用一台計算機來編寫代碼並將其輸入到代碼庫中。

也就是整個團隊一起用一台電腦同時開發軟體。

Teddy第一次聽到這種作法,腦中的第一個反應是出現黑人問號的畫面。Pair programming很合理,但整個團隊綁在一起用一台電腦開發,真的假的?!

***

初體驗

兩年多前Teddy幫忙帶幾個實驗室的研究生開發看板軟體—ezKanban,採用類似Scrum的方式開發,兩個禮拜Teddy和學生review一次進度,每次review會跟學生討論設計細節,包含design review與code review。雖然Teddy覺得自己已經把話講得很清楚,但常常在下次review的時候才發現學生的實作並沒有真的達到Teddy的要求,所以需要再解釋一次。長期以往雖然還是有迭代與增量,但整個ezKanban的開發進度總是不如Teddy的預期。

約略一年多前有一次機會,Teddy在實驗室跟團隊一起mobbing,那次的體驗並不好。首先,實驗室的空間並不大,Teddy這個人懶散慣了,不太習慣幾人擠在一個沒有方便伸展與走動的空間。其次,Teddy年紀大了,雖然實驗室mob環境有一台65吋大螢幕,但Teddy看著這個螢幕還是有點不太習慣。寫到這裡Teddy才突然想到,不一定是螢幕的問題,也有可能是實驗室椅子太難坐的關係。畢竟平常在家裡工作,Teddy坐的都是Herman Miller Aeron的高級人體工學椅XD。

總之Teddy的第一次mobbing經驗並沒有激起到自己繼續跟學生一起mobbing的想法。


▲要價不菲的人體工學椅

***

疫情的正面影響

為了Clean Architecture與領域驅動設計(Domain-Driven Design;DDD)課程的教學需要,Teddy自己也開發一套看板系統—cleanKanban,但因為Teddy前端不熟,所以cleanKanban一直就只有後端。

去年七月初暑假的時候,Teddy覺得這樣下去也不是辦法,ezKanban團隊開發一套看板系統,Teddy自己也開發一套。ezKanban團隊的前端做得還可以,但後端還差很多。Teddy的cleanKanban剛好相反,後端好棒棒,但前端……醒醒吧,你根本沒前端啊!

因為新冠肺炎疫情的關係,人們開始廣泛接受以線上活動取代實體活動。Teddy也受到這個正面的影響,去年七月暑假剛開始,Teddy決定把cleanKanban合併到ezKanban裡面,並且跟ezKanban團隊一起mobbing。但Teddy採用skype遠端連線的方式,ezKanban團隊在實驗室mobbing,並分享桌面給Teddy。如此一來,Teddy不用出門,可以舒舒服服坐在家裡的電腦前面玩貓兼用嘴吧寫程式

有此工作環境,夫復何求!

▲Teddy在家裡遠端參與ezKanban團隊的mobbing實況


***

全新的體驗

換個合作模式之後,去年暑假ezKanban進度大爆發。Teddy覺很棒,於是暑假過後繼續跟學生約定每周mobbing的時間。

▲上學期ezKanban團隊mobbing時間表


從去年至今Teddy已經連續和ezKanban團隊mobbing了近七個月,每周平均約20小時,累積mobbing時數應該已超過500小時。

下一集Teddy從敏捷與精實開發的角度來細談為什麼mobbing是一種好的開發模式。

***

友藏內心獨白:看似浪費實則精實。

2021年1月19日 星期二

領域驅動設計學習筆記(16):領域模型要放什麼東西?

Jan. 01 10:00~11:07


客人的問題

上周末在【領域驅動設計與簡潔架構入門實作班】有學員問Teddy…

學員:DDD的building blocks包含Entity、Value Object、Aggregate、Service、Repository、Factory等,為什麼你的domain model裡面沒有畫出Repository?

Teddy:為什麼要在domain model畫Repository?

學員:因為我們要「派工」啊。

Teddy:派工 ?!

學員:對啊,我們要畫設計圖,然後派工給工程師去寫程式。

***

領域模型作為瞭解問題的工具

領域驅動設計是透過「建立領域模型」來驅動整個軟體開發設計的方法。模型屬於solution domain,如果採用最常見的物件導向分析設計方法,領域模型的主角就是代表問題領域裡面重要概念的「物件」。

例如,開發看板系統,在「看板系統」這個問題領域中,重要的概念包含Kanban Board、Workflow、Stage、Swimlane、Kanban Card、WIP Limit、Flow、Lead Time等,它們自然成為領域模型的當然候選人。

你在跟看板的領域專家討論問題時,會出現Repository或Factory這種概念嗎?應該不會吧!所以,你不會在領域模型看到它們。

***

但是我要派工啊

好、好、好,Teddy知道你要派工。領域模型首先作為了解問題領域的分析工具,最後當然還是要用程式碼實作出來。傳統OOAD透過「模型轉換」過程,將分析模型轉成設計模型再轉成實作模型。但DDD希望針對同一個bounded context,整個開發過程就只有一個模型,用這個模型作為領域專家與團隊的通用語言(ubiquitous language),最後再將通用語言用程式碼實作出來,達到ubiquitous language in code的境界。

想要將DDD的領域模型再轉成詳盡的設計模型然後拿給程式設計師去寫程式(完成一個派工的動作XD),是waterfall的做法。如果號稱使用DDD但還是採用這種做法,代表團隊根本沒有共通語言,所以才需要使用另一種語言(派工文件)來溝通

看到領域模型中的Aggregate,自然就知道需要搭配一個Repository來負擔持久化(把Aggregate狀態存到資料庫中)的責任,根本不需要在領域模型裡面表達這種關係。

***

DDD為什麼流行?

DDD藍皮書2004年出版至今也過了10幾年,為什麼近幾年才流行?Teddy認為除了很多人想透過DDD來開發微服務系統以外,另一個原因就是DDD、Event Storming與Clean Architecture、TDD這些做法全部加起來,非常適合用來作為落實敏捷開發的一種實踐方法,符合目前整個軟體開發的主流做法,做得好可以讓你的軟體變軟。

軟體變軟,才能夠支撐公司業務變得更敏捷(靈活)。DDD是domain-driven design,不要搞成document-driven design。

***

友藏內心獨白:軟體開發的特性就是「按圖施工,保證不成功。」

2021年1月10日 星期日

領域驅動設計學習筆記(15):拿掉領域事件所造成的跨Bounded Context原始碼依賴關係

Jan. 10 22:29~23:59

▲圖1:ezKanban三個bounded contexts之間訊息流動方向


領域事件造成的原始碼相依性

上一集〈領域驅動設計學習筆記(14):依據領域事件流動方向調整Bounded Context的依賴關係〉提到依據領域事件流動方向將ezKanban的bounded context依賴方向由原本的:

  • Team—>Account
  • Team—>Board

調整成如圖1所示的:

  • Team—>Account
  • Board—>Team


請參考圖2,以UserRegistered領域事件為例,當使用者成功註冊之後,系統會自動幫該使用者建立一個預設的Team(團隊),當使用者登入系統之後,就可以在這個預設的團隊裡面新增Board(看板)或Project(專案)。

▲圖2:UserRegistered領域事件由Account bounded context傳遞到Team bounded context

ezKanban雖然切成三個bounded context,但目前採用Monolithic(單體)佈署方式,因此三個bounded context透過一個共享的in memory event bus來發送與接收領域事件。圖3展示位於Team bounded context的event handler—NotifyTeam程式,它監聽UserRegistered領域事件,當該事件發生時,呼叫CreateTeamUseCase幫剛註冊的使用者新增一個預設的團隊。


▲圖3:NotifyTeam事件處理程式

看到這裡鄉民們應該就很清楚,基本上Account與Team是兩個獨立的bounded context,彼此之間只有在runtime(程式執行期間)透過領域事件產生相依,compile time(編譯期間)原則上是不需要產生原始碼相依性。但因為一開始Teddy與ezKanban團隊偷懶的關係,讓Team直接去聽Account的UserRegistered領域事件,因此Team需要將UserRegistered類別import進來,所以產生Team對Account bounded context的原始碼依賴。

***

拿掉原始碼依賴

拿掉Team對Account bounded context的原始碼依賴也不會很麻煩:

  1. 設計一個RemoteDomainEvent類別,用來代表跨bounded context的領域事件,並將它放在所有專案都會參考的共用模組裡面。
  2. 不要直接把UserRegistered類別傳給Team,而是把UserRegistered「序列化」(例如轉成JSON格式)之後用RemoteDomainEvent將它包起來再傳出。
  3. Account不再監聽UserRegistered領域事件,改監聽RemoteDomainEvent。當收到RemoteDomainEvent之後,將其內容打開判斷是否為UserRegistered領域事件,如果是再執行原本的事件處理程序。


請參考圖4,NotifyAccount是位於Account bounded context的事件處理程式,它監聽自己的UserRegistered領域事件,並將其轉成RemoteDomainEvent。


▲圖4:NotifyAccount事件處理程式


圖5展示新的NotifyTeam事件處理程式,它改成監聽RemoteDomainEvent,並依據事件的tag與事件名稱將其轉交給合適的事件處理程式來處理。


▲圖5:新的NotifyTeam事件處理程式


將原始碼相依性徹底拿掉,從佈署的角度來看,要從Monolithic(單體)轉成Microservices(微服務)對系統架構來講要改動的幅度也就比較小,增加佈署方式的選擇彈性。

***

依賴依然存在

最後提醒一點,Account與Team這兩個bounded context,從Context Map的角度來看,應屬於Customer/Supplier的上下游關係,所以兩者之間還是有依賴關係,只不過這個依賴關係由原始碼依賴改成符合真實世界狀況的執行期間的訊息依賴。如果Account的UserRegistered領域事件介面改變,還是有可能會導致Team發生執行期間錯誤(runtime exception)。

***

友藏內心獨白:動態比較有彈性也比較容易出錯XD。

2021年1月8日 星期五

看懂一本書

Jan. 08 16:47~17:58


看完一本書

Teddy在北科上課的時候,經常會告訴學生利用研究所求學期間培養一種學習體驗:「把一本專業書籍從頭到尾讀完、讀懂」

對軟體開發這種知識工作者而言,學習速度就是軟體開發的瓶頸。如果在求學階段就具備「看懂一本書」的能力,畢業之後面對各種新知,學習起來也就不會覺得特別困難。即使覺得困難,也不會覺得是一件不可能的任務,因為你曾經達成過這種任務,體驗過看懂一本書的Quality Without A Name。

***

打賭

去年秋天開學的時候,Teddy問修「敏捷與精實軟體開發」課程的同學有沒有人曾經把一本專業書從頭到尾讀完的經驗?班上只有一位同學舉手。Teddy問他,你讀完的是什麼書?他說:「Clean Architecture」。

Teddy跟這位學生說:「我問你一個Clean Architecture的問題,如果你答對,這門課就直接及格,可以不用來上課。如果答錯,就退選,好不好?」

同學拒絕了。

Teddy想要測驗一下這位同學對於自己「看完一本書」的信心指數,因為Teddy所謂的「看完一本書」,是指「把這本書看懂」,不是表面上把書「看完(翻完)」而已。

***

怎麼算是把書看懂?

「看懂一本書」是一個很抽象的概念,而且看懂的層次也會隨著讀書的次數與自身體驗的增長而有所不同。Teddy有幾個自己土法煉鋼的方法:

  • Teddy在「增進學習力的三個練習」提到,可以透過了解專業名詞定義、有能力用一般人可以聽懂的比喻來解釋專業術語、看到解決方案之後,可以反推論出這個解決方案所要處理的問題是什麼(problem before solution,問題先於解決方案)這三個方法來讀書。
  • 自問自答,問自己為什麼。例如,學習Design Patterns的時候,學到Adapter設計模式,可以問自己:為什麼要用Adapter?Adapter要解決什麼問題?沒有Adapter之前的世界長什麼樣子?遇到相同問題,除了Adapter以外,還有哪些的解決方案?是什麼因素導致你選擇Adapter而不選擇其他解決方法?每問一個問題,就等於幫自己的知識累積一個層次,問題問多了,也就很難遇到可以把你問倒的人。
  • 實踐。書上很多知識,如果只是透過「腦袋中的理解力」去學習,哪只是學了一半,另一半落實(實作)能力還是要靠自己動手。建築師Alexander說:「A pattern is a process and a thing」從智力上去理解一件事,只是知道這個Thing,要動手去做,才能了解Process。特別是對於軟體開發人員而言,「知道」設計模式、單元測試、CI/CD、TDD、DDD、Clean Architecture、CQRS、微服務,但卻沒有動手做過,這樣的知道,不能算是真的知道。
  • 多看幾遍 (迭代)。好書,不是一次就可以讀完、讀懂。所以,多看幾遍,隨著自己的生活體驗不同,每次都可以看到不同的東西。

***

再續前緣

昨天Teddy在北科的課程期末考,沒想這位剛開學時說過讀完Clean Architecture的這位同學念念不忘這件事,希望Teddy下禮拜學期最後一週可以問他一個Clean Architecture的問題,他想挑戰自己的學習成果。

就如他所願,下禮拜問他一個Clean Architecture的問題。鄉民們可以預測一下,同學會不會答對呢?下周在「搞笑談軟工FB社團」公布對決結果。

***

友藏內心獨白:沒賭注就不刺激了啊XD。

2021年1月5日 星期二

領域驅動設計學習筆記(14):依據領域事件流動方向調整Bounded Context的依賴關係

Jan. 05 13:45~17:38

▲事件流動方向也代表bounded context之間依賴的方向


今天談一個開發ezKanban時,只專注在core domain而沒有同時關照到context map所踩到的坑 。


背景

ezKanban目前有四個Bounded Contexts:

  • Account:負責註冊。
  • Team:負責管理團隊、專案、以及看板的使用權限。
  • Board:負責表達看板中的工作流(Workflow)以及卡片(Card),此為ezKanban的核心領域(Core Domain)。
  • Report:負責產生累積流量圖(Cumulative Flow Diagram;CFD)、交期分布圖(Lead Time Distribution Chart)、控制圖(Control Chart)等圖表。


這幾天ezKanban團隊正在開發Add Member To TeamAdd Member To Board的使用案例,原本的設計Add Member To Team屬於Team Bounded Context,而Add Member To Board則是屬於Board Bounded Context的功能,如圖1所示。

▲圖1:Team與Board Bounded Contexts的domain model(部分)

***

問題

Add Member To Team做完之後緊接著要做Add Member To Board,此時發現:

  • Board member必須是team member,因此Add Member To Team需要接受前端傳來的List<Team Member>當作參數。
  • Team bounded context的Team member被移除之後,很顯然地Board bounded context的board member也要被移除。
  • 因為Team與Board屬於不同Bounded Context的不同Aggregate,因此彼此之間的狀態同步要透過領域事件達到最終狀態一致性。

到目前為止看起來都沒什麼問題,問題出在:

  • Team會去聽Create Board所產生的BoardCreated領域事件,以便在它身上加上一個Board物件,作為在團隊儀表板功能顯示給使用者看。
  • Board也要聽TeamMemberRemoved領域事件,以便將自己身上的Board member移除。

如此一來,Team和Board這兩個bounded context便產生循環參考

***

真理之源 (Source of Truth)

Team和Board因為領域事件產生耦合,在分散式系統中,可以在它們兩個之間架上Message Queue,以隔開兩者的直接相互參考。這樣做程式可以動沒問題,但這個現象讓Teddy思考:「兩個Bounded Context互相參考,是否意味著Board bounded context裡面的board物件,應該移到Team bounded context裡面?」

ezKanban的開發順序,先從Board bounded context這個core domain開始,此時主要關注點是工作流程是否可以表達問題領域的各種狀況,以及卡片的設計與流動,等於乎應看板的三個核心原則:

  • 視覺化
  • 限定WIP
  • 管理工作流

所以一開始代表「看板」概念的領域物件—Board被設計放在Board bounded context,等到board bounded context基本功能完成之後,團隊才開始實做Team bounded context,一直到實作至Add Member To Board才發現上述相互參考的問題。

Board這個概念,原本在Team bounded context與Board bounded context都存在,這沒問題。ezKanban的問題在於:「新增Board的時候,這個代表Board資料的Source of Truth應該要存在Team bounded context,而不是存在Board bounded context。」為什麼?現在想想也很簡單,因為從使用者操作ezKanban的時間順序來看,使用者是先在Team bounded context新增一個Board,接著才進入這個Board去設計工作流程與卡片,如圖2。


▲圖2:Team bounded context設計好之後,很明顯可以看出,Board的原始資料應該存放在Team裡面

***

友藏內心獨白:訊息流動的方向也要注意。

領域驅動設計學習筆記(13):什麼時候不要用領域驅動設計

Jan. 04 23:14~Jan. 05 00:12

▲照片與內文無關XD


問題

去年(2020)在上【領域驅動設計與簡潔架構入門實作班】有學員問Teddy:「有沒有什麼情況不要套用領域驅動設計(Domain-Driven Design;DDD)?」

***

問題領域

從問題領域(Problem Domain)的角度來看,Teddy認為以下幾種狀況明顯不適用:

  • 問題過於簡單:DDD藍皮書《Domain-Driven Design: Tackling Complexity in the Heart of Software》的副標題已經說明,這是一種解決軟體複雜性的方法,因此如果你要處理的問題很簡單,就不需要動用到DDD。問題是:「你怎麼知道你的問題是屬於簡單或是複雜的問題?」Teddy有兩種判斷的方法:
    • 一個Bounded Context就可以解決:如果你的問題不需要切成好幾的Bounded Contexts就可以解決,通常代表這個問題比較單純,也許用傳統OOAD方式來處理就可以。
    • 屬於Cynefin framework裡面的simple problemCynefin framework是敏捷開發經常引用的一個框架,它將問題分成四種—Simple、Complicated、Complex、Chaotic,如果你的問題屬於Simple類型,也就是事情的因果關係非常清楚,那麼有很大的機會不需要動用到DDD就可以把問題解決。
  • 問題夠複雜但屬於非核心領域(Core Domain):有時候你的問題很大且複雜,但是你負責的Bounded Context不是系統的核心,只是Generic Subdomain,例如權限管理。在這種情況下,就不需要堅持一定要使用DDD。
  • 缺少領域專家配合:DDD強調開發團隊與領域專家密切合作,如此才能建立合適的領域模型與通用語言。如果你的專案缺少領域專家的密切配合,很難發揮DDD的最大藥效。
  • 查詢功能:依據CQRS的做法,只有在Command端(會修改系統狀態的使用案例)才需要套用DDD。如果是不會改變系統狀態的Query(查詢功能),則不需要設計領域物件,直接從資料庫「生出」前端所需的Read Model或稱為View Model即可。因為查詢不需要領域物件,因此也就不會使用到DDD。

***

解決方案領域

從解決方案領域(Solution Domain)的角度來看,Teddy認為以下幾種狀況代表團隊的技術還不成熟,也許需要練功一下,或是找技術專家一起配合開發,否則斷然在專案上採用DDD,可能會採不少雷且只有「事倍功0.1」的產出:

  • 不懂如何建立領域模型:DDD的一個重點就是透過領域模型作為通用語言的骨幹,這個領域模型可以是物件導向模型、函數模式或程序模型,但一般比較常見的還是物件導向模型。以物件導向模型為例,既使在台灣業界,不少程式設計師最熟悉的還是資料模型,或是透過使用者介面來塑模領域物件,這樣做出來的領域物件,應該是很難達到Ubiquitous Language in Code的標準。
  • 沒寫自動化單元測試:在建立領域模型與達到Ubiquitous Language in Code的旅程上,經常需要不斷調整領域模型,甚至Bounded Context的邊界也可能會略作調整。在這種情況下,如果沒有自動化單元測試(use case level與method level的單元測試)作為安全網,很難在一定的成本之下持續精進領域模型。

***

代價

引入任何新的方法,都有適合與不適合的Context,以及相對應要付出的代價。Teddy認為DDD整套用下來,的確可以達到「讓軟體變軟」的最終目的,但學習門檻還是有的。

在「讓軟體看起來可以動就好」以及「讓軟體變軟」之間,還有很大的取捨空間。要不要用DDD,要怎麼用,還是要看公司、專案、團隊的特性再來決定,不要只聽別人說好棒棒就搶著用。體質不好,可能虛不受補,藥吃多了身體也不見得會有起色。

***

友藏內心獨白:我覺得好的東西你不一定會喜歡啊。

2020年12月29日 星期二

領域驅動設計學習筆記(13):幫Event Storming加上使用者介面

Dec. 29 09:43~11:39


問題

這個月底Teddy去客戶家上了三天的【領域驅動設計與簡潔架構入門實作班】,有好幾位學員都問到:「Event Storming怎麼表達使用者介面設計?」使用者介面是軟體的外觀,關係著軟體好不好看以及好不好用,的確是軟體開發中一個重要的議題。

今天來談談這個問題。

***

Event Storming簡介

Event Storming(事件風暴)在領域驅動設計中經常被使用於讓利害關係人與團隊共同協作,用以釐清業務流程、討論商機、風險、區分bounded context、建立共通語言,乃至於設計與實做軟體的一種方法。Event Storming發明人Alberto Brandolini在《Introducing EventStorming》書中介紹這個方法,圖1為Event Storming工作坊所使用的主要便利貼,不同顏色有不用的用途。


▲圖1:Event Storming常用便利貼顏色與意義


依據《Introducing EventStorming》書中的介紹,Event Storming有三個階段,分別為:

  • Big Picture:依據時間發生先後,在一面「巨大」的牆上,貼上Domain Event、External System、People,並藉此流程觀察Hot Spot(對商業流程有模糊不清、商機、痛點等)。
  • Process Modeling:基於前一個階段的產出,加上Read Model、Policy、Command。
  • Design:加上Aggregate。

一般網路上常看到的Event Storming產出物如圖2所示。


▲圖2:Event Storming示意圖

***

UI/UX設計

▲圖3:《Introducing EventStorming》書中的「The picture that explains everything」


參考圖3,在Event Storming方法中原本就涵蓋了UI/UX。這張圖可以這樣解讀:

***

使用者要使用軟體系統執行某項任務,為了執行這項任務,他需要參考資料以協助他決策判斷。因此,他在真實世界看到一個畫面,這個畫面是由Read Model(綠色便利貼)所產生。例如,你去餐廳吃飯,為了點餐(執行任務)你需要看到菜單(畫面),這個餐單可能是中文、英文、日文,可能只有文字或是圖文並茂,但菜單背後都是該餐廳的菜單資料(Read Model)所後製而成。如何設計給客人看的菜單就牽扯到UI/UX的議題。

使用者獲得足夠決策資訊後,向系統發出一個命令(Command,藍色便利貼),這個命令交給系統中某個聚合(Aggregate,黃色便利貼)去執行,執行完畢後發出一個領域事件(Domain Event,橘色便利貼)。領域事件可能引發後續的處理流程,稱為Process、Rule或Policy(紫色便利貼),後續處理流程再執行另一個命令。例如,告訴服務生(Aggregate)你要點餐(Command),服務生完成點餐動作後產生Order Placed(Domain Event)。Order Placed觸發一個後續處裡的流程—請廚師出菜,因此呼叫「製作餐點」這個Command。

領域事件也可能是由外部系統(External System,粉紅色長方形便利貼)所產生,例如餐廳可能與Uber Eat或Foodpanda合作,由外部系統觸發Order Placed領域事件。

最後,領域事件代表「狀態改變」,因此可從領域事件產生Read Model,再透過這個Read Model製作使用者介面。例如廚師可以從Order Placed領域事件產生「出菜順序」的畫面,作為製作餐點的決策參考資料。

***

範例

看完上述對於「The picture that explains everything」 的說明,在Event Storming中加上使用者介面就很容易了。圖4展示在ezKanban中,Create Project與Move Board To Project這兩個命令(套用Clean Architecture之後,這兩個命令被實作成兩個Use Cases)。使用者介面加在綠色便利貼之前,為了執行Create Project,使用者看到一個畫面,按下Add按鈕,跳出一個New Project 對話框,輸入Project Name按下Submit,把team id與project name當作參數呼叫Create Project使用案例。該使用案例透過Team Aggregate產生一個Project,然後發出Project Created領域事件。該事件代表有一個新的Project產生,因此使用者在執行Move Board To Project使用案例的時候,就可以從畫面看到剛剛新增的Project。


▲圖4:ezKanban範例,在Event Storming加上使用介面。

***

使用者介面如何產生

團隊的UI/UI的人員,可以沿用原本熟悉的工具來繪製使用者介面或是UI操作流程圖,只要將最後的結果截圖貼在Miro上面即可(Teddy與ezKanban團隊使用Miro來繪製Event Storming),不會影響原本的UI/UI設計流程。

最後工商服務一下,想學習DDD + Event Storming + Clean Architecture + TDD,歡迎報名泰迪軟體的領域驅動設計與簡潔架構入門實作班

***

友藏內心獨白:無縫接軌。