Cribbb是一個使用DDD聚合根和領域事件Domain Events概念開發的PHP開源通知框架:cribbb/cribbb · GitHub
幾乎所有Web應用都有一個通知提醒系統,這些通知系統都有共有的屬性和功能:
一個發往用戶的消息管道
Cribbb通知系統扮演一種消息管道,通知用戶最近的事件,有許多不同的“鉤子”可以觸發通知添加到用戶的消息管道中。
一個消息可以是任何類型
有許多不同的通知類型,針對應用中發生的不同的可能動作。
應當由可讀和未讀狀態
通知消息應該有狀態,一旦用戶有打開動作從而改變通知消息的狀態,這是很重要的用戶界面設計。
發送Email和作為UI一部分現實
默認情況用戶會收到一份Email,和用戶界面提醒一樣,用戶可以關閉郵件通知。
一個動作可以引起許多通知
在Cribbb中一個動作可以引起發給一個或多個用戶的通知,這意味著應當在動作和通知之間解耦。
通知消息應該被隊列化
使用隊列系統發送通知,因為針對一個動作可能有大量Email發送,通知發送不必即時。
通知是發送給用戶的一個消息,告訴他們他們對應用中感興趣的事件發生了,也許是一個用戶follow了他,或回復了他的帖子。
Domain Events是易于針對應用中事件的發生實現相應的通知機制的,當一個領域事件發送時,注冊的監聽器類將自動引爆,這樣動作和事件實現解耦,我們可以根本無需接觸事件的觸發動作而添加事件的監聽器。
有界上下文
經過幾周發現了區分不同的限定上下文Bounded Conext 重要性,一個有界的上下文是作為保護維護統一內部模型的層出現,這對于大型應用很重要。
Cribbb有一個身份方面的有界上下文,功能有:包括注冊一個新用戶 following其他用戶,更新賬戶信息等。
那么通知功能是否有自己的有界上下文?或者是身份有界上下文的一部分?
通知功能其實應該屬于身份有界上下文:
首先,通知是用戶身份系統的一種重要概念,應用可以觸發一個通知,但是通知僅僅對于注冊有身份的用戶是重要的。
其次,在通知模型和用戶身份識別模型之間沒有矛盾,如果有,那么我們可能就區分為不同的有界上下文。
最后,一個通知沒有道理不和用戶綁定,一個用戶只能查看自己的通知,不能看其他用戶的通知,我們為Cribbb建立一個獲得通知的API,端點是:me/notifications.
通知實體和用戶聚合
通知應該作為實體建模,通常你默認會建立為值對象 而不是實體,因為簡單,但是這次我們沒有選擇。
通知沒有必要知道用戶上下文以外的事情,我們應當能夠從數據庫任意地接受消息,而不是只能從User對象獲得一個用戶的通知。
這意味著通知如果放在User聚合中很整潔合適。Notification通知實體也能非常簡單。
首先,通知需要一個內容體需要保存通知的內容文本數據。
其次,我們需要一個 已讀/未讀的狀態,我們需要通知消息被讀的時間戳,這樣我們能夠判斷這兩個狀態。
最后,我們分類通知以便可以過濾它們,在通知實體中使用一個關鍵詞來標識。