Newbe.Claptrap 項目週報 1,第一週代碼寫了一點。但主要仍是考慮理論可行性。html
第一次接觸本框架的讀者,能夠先點擊此處閱讀本框架相關的基礎理論和工做原理。git
週報是啥?
成功的開源做品,離不開社區貢獻者的積極參與。做爲一個新啓動的輪子項目,項目聯合創始人【月落】有交代:github
「我知道你代碼能力也不怎麼樣,你就把你的想法每週的交代清楚。讓他人看到項目的價值。等待愈來愈多的人發現項目價值所在的時候,天然就會給予更多的關注,甚至於參與的項目的開發當中。因此你要每週都寫一下週報。週報最好側重於講解項目的概念,以及經過項目如何解決實際問題。固然也能夠包含一些關於項目如何設計的內容,但要注意適度,一般你們不會太注意項目怎麼實現。而更關注項目帶來的價值。記住:只有產生了價值,項目纔會成功。」數據庫
因而筆者就只能每週寫一下週報,勉強維持生活這樣子。編程
輪有輪樣
新輪要有新輪的樣子,「項目開張篇」 中介紹了本框架相關的基礎理論和工做原理。鑑於相關的理論內容對於剛剛接觸的讀者較爲生疏,所以本節將前文最爲關鍵的內容羅列以下以激發讀者的回憶。併發
Actor 特性一:Actor 的狀態是經過外部調用 Actor 而改變的。框架
Actor 特性一補 1:Actor 的狀態不與外部進行共享。post
Actor 特性一補 2:外部能夠讀取 Actor 狀態。spa
Actor 特性二:Actor 是 「單線程」 工做的,每次只能處理一個請求。線程
Actor 特性二補 1:併發讀取狀態能夠不是 「單線程」。
框架定義的 Actor 類型——Claptrap:經過事件模式,產生事件並經過事件改變自身狀態的 Actor。
框架定義的 Actor 類型——Minion:與 Claptrap 對比,Minion 不產生事件而是讀取對應 Claptrap 的事件來改變自身的狀態。容許存在多個 Minion 對應一個 Claptrap。
經過 Claptrap 和 Minion 配合完成 「轉帳」 業務。
月落大佬名言警句 1:世界上本也不存在 「銀彈」。一套框架解決不了全部問題。
月落大佬名言警句 2:業務複雜度是不會由於系統設計變化而減小的,它只是從一個地方轉移到了另外的地方。
還沒輪影,先用輪跑
如今咱們擁有了 Claptrap 和 Minion 的概念。接下來,結合一些業務場景,實驗一下框架可否應對各類各樣的業務需求。
再美的技術手段沒法應對現實的需求與變化,那也只能技術花瓶。——剛剛學完賽博坦 XII 量子計算機指令集的月落
業務場景
這是一個簡單的電商系統:
- 只賣一種綠色的水晶,爲了方便描述,將這個商品命名爲 「原諒水晶」。
- 用戶可使用本身帳號中的餘額購買原諒水晶。餘額是經過外部支付系統充值進來的。充值部分,暫時不是業務場景須要考慮的。
- 每一個用戶還有一個積分,很巧,這個積分的圖標也是綠色的,所以,將這個積分命名爲 「原諒積分」。
- 原諒積分的獲取方式有不少,例如:用戶註冊;邀請其餘用戶註冊;被邀請用戶進行了消費,邀請者也能夠得到;原諒即挖礦;現實中得到了原諒;等等其餘的一些方式,這部分可能須要配合後續的活動持續增長得到方式。
- 原諒積分能夠在進行購買原諒水晶時,抵扣一部分須要支付的金額。
- 原諒積分在將來極可能有其餘的用途。
- 購買原諒水晶的支付方式將來極可能不止餘額和原諒積分兩種。
以上就是對於這個電商系統的一部分需求描述。需求將來確定是會變化的。
要素察覺
電商系統,最爲主要的業務場景天然是和商品的交易有關的業務場景。不論其餘的需求場景多麼的複雜,交易相關的業務場景必然是首當其衝須要分析解決的。
那麼首先,咱們將 「用戶確認購買原諒水晶」 這個場景用簡單的語言描述一下程序須要執行的業務內容:
- 須要檢查用戶的餘額是否足夠
- 假如用戶選擇了積分抵扣,須要檢查用戶的積分是否足夠
- 須要檢查庫存是否足夠
- 須要扣減用戶的餘額
- 須要扣減庫存
- 假如用戶選擇了積分抵扣,須要扣減用戶的積分
若是採用直接操做數據表的方式實現以上六個要點,對於絕大部分開發者來講應該是十分簡單的。開啓一個數據庫事務,至少具有行級鎖,將數據進行檢查和更新,即可以完成這個業務。那麼如今使用本框架進行實現,根據 「業務複雜度不減小」 的基本事實,也一樣須要實現以上六個要點。
未卜先知
首先,在不太討論依據的前提下,筆者圍繞上文提到的一些主體概念,設計瞭如下這些 Claptrap:
概念 | 英文命名 | 縮寫 | 表明顏色 |
---|---|---|---|
原諒水晶 | SKU | S | ■■■■■ |
原諒積分 | UserPoint | P | ■■■■■ |
用戶餘額 | UserBalance | B | ■■■■■ |
依軲轆畫輪
按照前篇的 「轉帳」 業務場景的流程設計,此處採用相同的方式設計一下購買的邏輯。以下圖所示:
分析一下這個設計方案:
依照業務邏輯的順序,完成了庫存檢查、庫存扣減、餘額檢查、餘額扣減、積分檢查、積分扣減的業務步驟。
注意 Client 和 Claptrap S 之間的調用線的存在時間,只有在一開始的時候,也就是說,客戶端僅須要稍做等待,即可以獲得響應。
Claptrap S 將事件推送給 Minion S 以後即可以繼續響應新的請求。確保了多個用戶進行併發購買商品即確保了商品不會超賣,也確保了響應事件足夠短。
整個業務邏輯的入口是 S、這樣能夠確保用戶在鎖定庫存的前提下進行支付,避免了用戶付了錢沒有辦法買到商品的狀況。
基於形狀上的緣由,這種設計方案被命名爲 「鍊形設計(Chain-Like Design)」。
同樣的材料,不同的輪子
也存在另一種設計方案。以下圖所示:
分析一下這個設計方案:
引入了一個新的 Claptrap W(What a amazing that I get a forgiven-crystal)做爲業務的入口,這個 Claptrap W 經過調用其餘的 Claptrap 實現這個業務過程。
相比與上節的設計方案,Minion S、P、B 都再也不參與業務的流轉控制,由於這些業務的流轉控制已經由 Claptrap W 進行控制。
而且因爲 Minion W 的存在,這個設計方案也能夠將部分的調用交由 Minion 來進行,因此這個方案也能夠是如下兩種形式。
基於形狀上的緣由,這種設計方案被命名爲 「樹形設計(Tree-Like Design)」。
那麼此處就出現了選擇,既然有出現了選擇,那麼此處就使用《月老闆的軟件開發小妙招三十二則》中記載的 「WhyNot 對比分析法」 來決定使用哪一種設計方案:
選項 | 爲何不? | 爲何!不! |
---|---|---|
鍊形設計 | 業務流轉過程的控制經過 Minion 相鏈接,這是一種緊耦合的設計。這至關於 Minion 和 Claptrap 此次操做業務的上下文。一個明顯的問題:客戶是否選擇了積分支付,這個邏輯,要麼在 Minion B 中判斷,要麼在 Claptrap P 中判斷,但不論哪一種方式其實都不合理。 這樣的設計在應對流程失敗的時候,會特別難以處理。例如在最後一步客戶若是積分不足,那麼可能就須要逐步回滾,這可能會很是困難。 |
|
樹形設計 | 這種設計,把業務的核心流程控制內容集中的一對相關的 Claptrap W 和 Minion W 中。這是一種高內聚的表現。 基於這種設計方案,很容易基於 Claptrap S、P、B 構建出更加複雜的過程。 |
其實讀者很容易發現,對於這個選擇的 WhyNot 對比分析表,實際上是一邊倒的。這裏明顯就是要選擇樹形設計。
《月老闆軟件開發小妙招三十二則》,是月落大佬在平常開發過程中對軟件開發過程用到的一些小方法的收集和概括。這些方法大多不是新發明的內容。月落大佬只是將這些方法收集在一塊兒,爲了啓示後來者,在分析判斷一些問題的時候,用一些小方法有時就能讓事情變得有條理一些。除了 「WhyNot 對比分析法」 以外,還有較爲知名的 「5W1H 需求描述法」;很是簡單的「CheckList 備忘錄」;被普遍說起的「艾森豪威爾法則」 等。
WhyNot 對比分析法,簡單來講就是要講選擇多個主體進行並排對比,分別列舉 「應該選擇它」 和「不該該選擇它」的理由,而後進行綜合判斷進而作出決定的方法。它特別適用於多人對某一選擇爭執不休時採用的方法,經過表格的形式分別記錄陳述的理由,確保了不缺不漏有理有據。在方法上的基礎,還衍生出了 「理由權重計量」、「人員話語權計量」 等其餘的一些變種。此方法與 「優劣對比法」、「異同對比法」 等對比法,以及 「機率選擇法」、「經驗選擇法」 等選擇法有必定的聯繫與區別。此方法的命名聽說是月落大佬獨創,是一個語法梗。在中文當中,能夠採用 「爲何不?」 這樣的反問句來表示選擇一個對象的理由,能夠用 「爲何!不!」 這個的祈使句來表示不選擇一個對象的理由。 WhyNot 其實就是對 「爲何不」 四個字的直譯。
好輪子外觀也好看
初見 WhyNot 對比分析法的讀者可能會有疑問:難道就沒有選擇鍊形設計的理由?
須要解釋的是, WhyNot 對比分析法是對固定場景的分析法,所以若是場景變了,分析的結果也會變。也就是說,在某些特定的場景下,鍊形設計有其必要性。
那麼在解釋以前,咱們採用另外的方法來解讀鍊形設計與樹形設計:
- 將 Claptrap 和對應的 Minion 合併
- 用 「由於… 因此…」 的句式來代替圖形中的實線調用
那麼結合上圖的鍊形設計就能夠表述爲:
- 由於 S,因此 B
- 由於 B,因此 P
展開的語義能夠是:
- 由於購買而扣除了庫存,因此進一步扣減餘額
- 由於購買而扣減了餘額,因此要進一步扣減積分
上圖樹形設計就能夠表述爲:
- 由於 W,因此 S
- 由於 W,因此 B
- 由於 W,因此 P
展開的語義能夠是:
- 由於購買,因此扣減了庫存
- 由於購買,因此扣減了餘額
- 由於購買,因此扣減了積分
即便筆者這裏解釋的不太清楚,可是讀者仍然能夠觀察 「由於購買而扣減了餘額,因此要進一步扣減積分」 這句其實不太合理,這二者在業務上其實不該該有明顯的來龍去脈。
這其實也是鍊形設計在這個場景下不能適用的緣由:若是二者的調用關係沒有明顯的來龍去脈,而將二者設計爲先後調用的鍊形關係。那麼極可能獲得的是不合理的設計。
那麼反過來講:若是要應用鍊形設計。二者之間必須存在合理的來龍去脈。
不過,在需求分析過程當中,當前可能必然存在的來龍去脈,事後可能就已經不太合理。業務場景的多變和需求的不徹底穩定,致使了事實上,採用樹形設計可以應對更多的問題。
讀者能夠嘗試對上文業務場景中剩餘的幾點需求進行一下設計。
另外,讀者能夠從新思考一下開張篇中所採用的 「轉帳」 場景的設計,採用樹形設計是否更爲穩當。
其實就是新輪子
在開張篇中,咱們將 Actor 模式與 CRUD 模式進行了簡單異同點比較。而如今還存在另一類比較常提到的設計方案,就是 「領域驅動設計」。
領域驅動設計的概念此處很少作介紹,對此內容比較陌生的讀者能夠參看微軟 MVP 湯雪華老師的文章《領域驅動設計之領域模型》
那麼,當讀者理解了領域驅動設計以後,再結合本篇前面提到的 Claptrap W、S、P、B。或許 Claptrap S、P、B 就是聚合根?或許 Claptrap W 就是應用服務?筆者認爲 Actor 模式實際上是對領域驅動設計的一種進一步發揮:
- 領域驅動設計沒有在設計模型內考慮業務併發,而 Actor 模式做爲一套併發編程模型其實就彌補了這部分的缺失。
- 絕大多數(筆者所知到的)領域驅動框架仍然採用了 「從倉儲還原聚合根,操做完畢後保存」 的通常過程。而以 Orleans 爲例的 Actor 框架會將已經激活的 Actor 在內存中保留一段時間,也就是說,聚合根能夠在內存中不斷的修改,而不須要重複的從倉儲中還原。
總的來講,讀者能夠沿用領域驅動設計的思路建模,而後嘗試將原有的聚合根和應用服務設計爲 Actor ,從理論上嘗試一下本身所熟悉的領域,可否採用 Actor 進行實現。或許讀者能夠從中發現一些不同的體驗。
不過,本框架因爲採用了 Actor 模式和事件溯源模式,所以設計方法與領域驅動模型相比有所繼承又不徹底相同,還有一些其餘須要注意的內容,會在後續整理出相應的文章。
結篇
本篇但願經過一個業務場景的設計,讓讀者瞭解到如何採用本框架的理論概念來實現業務。其中包含有一些做者的臆造詞,所以可能須要花費讀者更多的時間進行理解。
因爲做者的工做經驗有限,缺少豐富的行業領域知識,所以對於框架的設計理念是否符合特定行業特性的問題沒法給出準確的判斷,還須要讀者多加思考。如有任何須要協助的問題,歡迎聯繫本項目組。
歡迎對此感興趣的朋友關注項目,參與項目。
如下是一些與項目有關的連接,歡迎讀者查看:
- Github 倉庫地址,歡迎提 issue
- Gitee 倉庫地址,歡迎到 Github 提 issue
- 做者郵箱 newbe36524@qq.com
- 博客園
- QQ 羣 553474855
- http://www.newbe.pro
- 本文連接: http://www.newbe.pro/2019/03/08/Newbe.Claptrap/Newbe-Claptrap-Weekly-1/
- 版權聲明: 本博客全部文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!