事件風暴過程全體驗 - 下篇

在上一篇文章中,以英雄聯盟自動預警系統爲例子,展開了事件風暴獲得了上下文,這裏就繼續延伸,看看事件風暴的產物還可以怎麼進一步落到開發代碼上面。

Step1. 設計 API

結合命令風暴的結果我們發現有一部分的決策是外部觸發的(框起來的部分),那這部分我們就應該爲它們設計對應的 API

在 api/rest/CaseController.java:

 1@RestController
 2@RequestMapping("/case")
 3public class CaseController {
 4    @PostMapping
 5    public void createCase(@RequestBody String caseBrief) {}
 6
 7    @PostMapping("/{caseId}/close")
 8    public void closeCase(@PathVariable int caseId) {}
 9
10    @PostMapping("/{caseId}/esculate")
11    public void esculateCase(@PathVariable int caseId) {}
12
13    @PostMapping("/{caseId}/thief")
14    public void updateThiefInfo(@PathVariable int caseId,
15                                @RequestBody String thiefInfo) {}
16
17    @PostMapping("/{caseId}/fight-plan")
18    public void addFlightPlan(@PathVariable int caseId,
19                              @RequestBody FightPlanDTO fightPlanDTO) {}
20
21    @PostMapping("/{caseId}/fight-plan/{planId}/success")
22    public void markSuccessFightPlan(@PathVariable int caseId,
23                                     @PathVariable int planId) {}
24
25    @PostMapping("/{caseId}/fight-plan/{planId}/fail")
26    public void markFailFightPlan(@PathVariable int caseId,
27                                  @PathVariable int planId) {}
28}
29

這裏大體上遵循了 REST 的規則,充分使用 URL 指定所需的資源。當然,比如像 “關閉” 案件記錄“應該用 POST 還是 DELETE 這些細節地方也是可以進一步斟酌的。

把聚合根對應的實體和值對象,以及後面補充的一些關鍵屬性補充起來,暫時它還是一個貧血的 POJO:

 1public class CaseReport {
 2    int id;
 3    Timestamp startTime;
 4    Timestamp closeTime;
 5    String caseBrief;
 6    String thief;
 7    List<FightPlan> fightPlanList;
 8}
 9
10public class FightPlan {
11    int id;
12    String status;
13    String planDetail;
14    int meetingId;
15}
16

Step3. 構建應用服務和領域服務

這裏以系統收到升級預警通知的步驟爲例子:

場景與步驟:收到升級預警通知 -> 觸發升級預警

如果按我自己原來的寫法,我會把這個邏輯寫在應用服務層 ApplService 裏面。但是剛巧在 DDD 跟張逸老師協作了他的一個場景驅動工作坊,所以這裏嘗試用他的方式去規劃一下。

 1@Service
 2public class CaseReportService {
 3    @Autowired
 4    CaseReportService caseReportService;
 5
 6    @Transactional
 7    public void esculate(int caseId) {
 8        caseReportService.esculate(caseId);
 9    }
10}
11

步驟放在 DomainService:

碰巧這裏三個步驟都是調用底層服務,所以都是調用了 gateway/repository 去進行,如果當中有一些是不依賴與底層的動作,則應該充血地放到 DomainObject(CaseReport)裏面去。

到此,事件風暴對應下來,唯一還未補的缺應該就剩下底層所需的技術支撐了。比如 Rest 調用三方服務,或者是 DB 相關的 SQL。這個應該是 easy job 就不繼續寫了哈 ^_^

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/PuHTRfFQm8Xdo2bidFHADw