近期特別有感,炒熱了幾年的數(shù)據(jù)分析與數(shù)據(jù)行銷侄柔,他們都仰賴著原生的使用者在系統(tǒng)上產(chǎn)生的一系列的運(yùn)行軌跡,而這樣的數(shù)據(jù)源都要求著需要取得raw data,而不是被彙整過後的最終結(jié)果或當(dāng)前的資料樣態(tài)诅挑。
從大眾比較可以理解的一般常見的場景來看四敞,我們都知道關(guān)於銀行帳戶的存款簿:
當(dāng)你打開自己的存款簿,會很清楚的看到你的存提的歷程拔妥,每一次發(fā)生的時(shí)間忿危,金額,甚至其他外部參考註記(薪轉(zhuǎn)戶/他行轉(zhuǎn)帳等等) !
不過没龙,當(dāng)自己真的在做軟體系統(tǒng)的時(shí)候铺厨,我們卻經(jīng)常的只保留了當(dāng)前帳戶的資金總額,這兩者有個(gè)很明顯的差異
只關(guān)注最終的狀態(tài)?—?一般的CRUD 的風(fēng)格的系統(tǒng)皆是如此硬纤,某種程度上受了RDBMS的很大的影響力解滓。
關(guān)注每一次的互動(訊息)?—?從而留下了一系列對於真實(shí)事件的歷程,作為呈堂證供筝家。
讓我們從另一種角度來思考一件事情 !!!
如果在很多事情發(fā)生的當(dāng)下洼裤,我們僅只保留了最後的狀態(tài),而不去關(guān)注他的歷程溪王,那麼當(dāng)你需要對多變的領(lǐng)域事件(Domain Event)做追蹤時(shí)你就很難追了腮鞍。
舉個(gè)經(jīng)典的即時(shí)戰(zhàn)略遊戲(RTS) StarCraft 為例 !
打星際2的時(shí)候,經(jīng)秤猓看到非常多的播報(bào)員在面對雙方一番激烈的撕殺之後移国,然後激動地訴說著 在剛剛戰(zhàn)鬥過去的幾秒鐘裡頭
(1)雙方各損失了多少工兵
(2)經(jīng)濟(jì)上金礦與瓦斯的採集到的進(jìn)用與損耗狀態(tài),藉此評估依照過去
(3)幾秒鐘之間的數(shù)值差異變化
(4)在後續(xù)的幾分鐘以後雙方的優(yōu)勢差距可以到達(dá)幾倍?!
基於這種以”值得關(guān)注的事件”為基礎(chǔ)的系統(tǒng)設(shè)計(jì)芒珠,並且由事件發(fā)動者自己發(fā)出的訊息作為活生生的紀(jì)錄被保留下來桥狡,這種的模式稱之為 Actor Model。
The actor model promotes actors as the first-class unit of computation and emphasizes communication between actors via message sending.
在Actor model的概念當(dāng)中皱卓,每一個(gè)訊息的發(fā)動者都是一個(gè)Actor裹芝,例如
commandCenter.produceSCV();
scv.buildBarrack(new ExpectedPostion());
scv.cancelUnderConstructionBuilding(constructingBuilding);
在上述的部分,commandCenter?, scv 都是Actor的實(shí)例娜汁,而這類的Actor model的設(shè)計(jì)上都一併考量了非同步的機(jī)制嫂易,所以非常適合用在以下幾種領(lǐng)域:
高併發(fā)的請求訊息模型
交易系統(tǒng)
對於Actor 來說,由於他本身僅關(guān)注著自己所感興趣的事件 → 他自身能夠發(fā)起與接受的訊息事件!!
所以掐禁,每一個(gè)Actor 應(yīng)當(dāng)都盡可能地遵循單一職責(zé)的權(quán)責(zé)劃分去處理怜械,避免做了太多不該是他自己做的事情,就像星際當(dāng)中的scv就是只能建構(gòu)建築與微幅的反擊敵人傅事,但他就是無法做出其他更強(qiáng)大的火力支持缕允,他就是工兵而已。
看到這裡蹭越,讓我們稍微彙整一下障本,關(guān)於Actor Model:
Actor 只發(fā)出或接受他所能(想)理解的訊息事件
Actor 只可以接受(註冊)他能(想)理解的訊息事件
每一次Actor 發(fā)出的訊息事件,都是一個(gè)既定事實(shí)(Immutable Event),不可逆的(這不廢話驾霜,歷史不就都這樣來的!)
再把這樣的概念轉(zhuǎn)回到 Eric Evans 所倡導(dǎo)的DDD 來看案训,對於領(lǐng)域物件取用是從Aggregate Root開始,而領(lǐng)域物件之間彼此的溝通訊息則是Domain Event粪糙,而每一次的Domain Event 都是immutable (正好與前述特性一致)强霎,那麼我們可以:
用Actor Model 封裝 Domain Aggregate Root?!!!
用Actor Message 封裝Domain Message?!!!
似乎,透過Actor Model 的設(shè)計(jì)概念來實(shí)現(xiàn)DDD顯然變得是一件可以考慮的做法了!
從這樣的訊息模型的概念的基礎(chǔ)上蓉冈,可以得到幾個(gè)關(guān)鍵實(shí)用的特性
基於事件發(fā)布城舞,所以可以特別對有興趣的事件作註冊予以監(jiān)看,使得日後針對各種多變且多元的想關(guān)注的事件可以從容地取得資訊洒擦,每一次的事件都被活生生的記錄下來(Immutable fact/event)椿争,而你要做的事情就是去添增新的訊息接收者(Another actor)怕膛。
特別強(qiáng)調(diào)單一職責(zé)這與DDD 當(dāng)中特別提到的 Domain in Context不謀而合熟嫩,不要先射箭再畫靶這樣肯定會走遠(yuǎn)跑偏了,明確的勾勒出範(fàn)圍自然可以有限度合理的找出Actor褐捻。
把真正需要被關(guān)注的事件主題找出來即可掸茅,不要把Actor 自己內(nèi)部的一些***無關(guān)痛癢的狀態(tài)變化特別暴露成事件,這樣只會產(chǎn)生信息爆炸***柠逞,如果真要有個(gè)紀(jì)律來做這些判別的話昧狮,或者可以考慮從Actor 所暴露的public method 範(fàn)疇來做初步篩選,真的公開出去做交互的訊息才認(rèn)真思考他是否是個(gè)合理的Event板壮。
面對現(xiàn)在期望的即時(shí)數(shù)據(jù)分析與獲取逗鸣,在知名的[HTAP]概念之下,要能快速的獲取多元的數(shù)據(jù)源绰精,從添增事件註冊的Actor的方式之下撒璧,可以較為無痛的不干擾到既有的Actor(透過註冊達(dá)成群播的訴求),又能動態(tài)收取期望的數(shù)據(jù)笨使,這是一種可以被參考的方法之一卿樱。
對於Actor Model當(dāng)中的 Actor 該怎麼捕捉?
個(gè)人覺得現(xiàn)在處在一種沒辦法完整的定義的理解上,傳統(tǒng)上理應(yīng)遵循著DDD 的建議風(fēng)格硫椰,從領(lǐng)域概念抓出Entity繁调,然後試圖去發(fā)現(xiàn)他是否可能基於行為產(chǎn)生event,從而確認(rèn)他的存在的可識別性靶草,若他確實(shí)是Entity而非 Value Object蹄胰,並且去思索這領(lǐng)域物件的生成原因與其相依性,則能更細(xì)一步去找出他可能對應(yīng)的生成源頭(Aggregate Root)奕翔,以及其他的物件(Service?, Repository?, factory?… etc )
但是這樣的設(shè)計(jì)風(fēng)格裕寨,在面對 ATDD/TDD 的浪潮狂襲之下,這樣的Up-front design 似乎真的很不被認(rèn)同或理解糠悯,至少我在參加過得很多關(guān)於敏捷社區(qū)開辦的設(shè)計(jì)課程裡頭帮坚,都將 up-front desgin 的理念束之高閣妻往。
我個(gè)人認(rèn)為,實(shí)際上DDD與 ATDD/TDD 的設(shè)計(jì)風(fēng)格理念试和,在面對要以Actor Model 進(jìn)行軟件開發(fā)時(shí)讯泣,並不盡然是個(gè)完全的衝突,反而倒是可以各取優(yōu)勢的組合一併來探討:
讓ATDD/TDD 盡可能地闡述期望( produced Immutable Domain Event)阅悍,並讓User Story 本身是個(gè)有價(jià)值(meaningful process to show out intent in domain context)的Story好渠。
利用TDD的過程,讓重構(gòu)不斷的反饋初期設(shè)計(jì)出來的 Domain Event去看看他是否能在單一一個(gè)領(lǐng)域物件當(dāng)中完成單一職責(zé)的責(zé)任节视,若不能則參考DDD的設(shè)計(jì)精神去逐漸長出他可以配套關(guān)聯(lián)出來的 Aggregate root, Value Object?, Service?, Repository?, Factory?… etc
PS: 近期小弟大病一場拳锚,稿子寫得實(shí)在慢啊 ~