事件风暴过程全体验-下篇

简介: 事件风暴过程全体验-下篇

在上一篇文章中,以英雄联盟自动预警系统为例子,展开了事件风暴获得了上下文,这里就继续延伸,看看事件风暴的产物还可以怎么进一步落到开发代码上面。


这里我们聚焦案件记录上下文,假设它独立为一个服务存在。然后我们可以把它对应的决策/命令搬过来一起看:

image.png


Step1. 设计API



结合命令风暴的结果我们发现有一部分的决策是外部触发的(框起来的部分),那这部分我们就应该为它们设计对应的API


在api/rest/CaseController.java:


@RestController
@RequestMapping("/case")
public class CaseController {
    @PostMapping
    public void createCase(@RequestBody String caseBrief) {}
    @PostMapping("/{caseId}/close")
    public void closeCase(@PathVariable int caseId) {}
    @PostMapping("/{caseId}/esculate")
    public void esculateCase(@PathVariable int caseId) {}
    @PostMapping("/{caseId}/thief")
    public void updateThiefInfo(@PathVariable int caseId,
                                @RequestBody String thiefInfo) {}
    @PostMapping("/{caseId}/fight-plan")
    public void addFlightPlan(@PathVariable int caseId,
                              @RequestBody FightPlanDTO fightPlanDTO) {}
    @PostMapping("/{caseId}/fight-plan/{planId}/success")
    public void markSuccessFightPlan(@PathVariable int caseId,
                                     @PathVariable int planId) {}
    @PostMapping("/{caseId}/fight-plan/{planId}/fail")
    public void markFailFightPlan(@PathVariable int caseId,
                                  @PathVariable int planId) {}
}


这里大体上遵循了REST的规则,充分使用URL指定所需的资源。当然,比如像“关闭”案件记录“应该用POST还是DELETE这些细节地方也是可以进一步斟酌的。

Step2. 构建领域对象



把聚合根对应的实体和值对象,以及后面补充的一些关键属性补充起来,暂时它还是一个贫血的POJO:


public class CaseReport {
    int id;
    Timestamp startTime;
    Timestamp closeTime;
    String caseBrief;
    String thief;
    List<FightPlan> fightPlanList;
}
public class FightPlan {
    int id;
    String status;
    String planDetail;
    int meetingId;
}


Step3. 构建应用服务和领域服务


这里以系统收到升级预警通知的步骤为例子:

场景与步骤:收到升级预警通知 -> 触发升级预警


  • 校验所升级预警的案件存在
  • 创建线上会议
  • 把会议登陆URL发送通知给其他英雄


如果按我自己原来的写法,我会把这个逻辑写在应用服务层ApplService里面。但是刚巧在DDD跟张逸老师协作了他的一个场景驱动工作坊,所以这里尝试用他的方式去规划一下。


场景放在App Service:


@Service
public class CaseReportService {
    @Autowired
    CaseReportService caseReportService;
    @Transactional
    public void esculate(int caseId) {
        caseReportService.esculate(caseId);
    }
}


步骤放在DomainService:


@Service
public class CaseReportService {
    @Autowired
    CaseReportRepository caseReportRepository;
    @Autowired
    FightPlanRepository fightPlanRepository;
    @Autowired
    MeetingGateway meetingGateway;
    @Autowired
    NotificationGateway notificationGateway;
     public void esculate(int caseId) {
        final CaseReport caseReport = caseReportRepository.getCaseReportById(caseId);
        if (caseReport != null) {
            final MeetingInfo meeting = meetingGateway.createMeeting(caseReport);
            notificationGateway.sendEsculationMsg(meeting);
        } else {
            throw new BizException(INVALID_CASEREPORT_ID);
        }
    }
}


碰巧这里三个步骤都是调用底层服务,所以都是调用了gateway/repository去进行,如果当中有一些是不依赖与底层的动作,则应该充血地放到DomainObject(CaseReport)里面去。


至此,一个分层架构大概出来了,并且已经完成了业务domain的开发以及API的入口:

image.png


分层架构



最后,聚合细化的信息其实也是可以对应给DB设计指引的:

  • 1-1的场景下,可以合在一个表,可以两个表
  • 1-n的场景下,通常两个表,也可以三个表
  • n-n的场景下,通常三个表


对应我们的例子,可以这样来设计表结构:


CREATE TABLE case_report_tbl (
  id int NOT NULL AUTO_INCREMENT,
  case_brief varchar(255) NOT NULL,
  start_time TIMESTAMP NOT NULL,
  close_time TIMESTAMP NOT NULL,
  thief varchar(255),
  PRIMARY KEY (ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE fight_plan_tbl (
  id int NOT NULL AUTO_INCREMENT,
  status varchar(10) NOT NULL,
  plan_detail varchar(255) DEFAULT NULL,
  meeting_id int NOT NULL,
  case_id int NOT NULL,
  PRIMARY KEY (ID),
  FOREIGN KEY (case_id) REFERENCES case_report_tbl(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


当然,现在也有很多是推荐不用FOREIGN KEY的设计手法,开放式无约束地建表,并把校验的逻辑都回归到代码里面并使用自动化测试去保证这个必须的逻辑校验,所以这里也只是一个指引,大家可以按需谋划。


到此,事件风暴对应下来,唯一还未补的缺应该就剩下底层所需的技术支撑了。比如Rest调用三方服务,或者是DB相关的SQL。这个应该是easy job就不继续写了哈 ^_^

相关文章
|
测试技术 领域建模 定位技术
基于事件风暴的需求分析 | 方法案例一
事件风暴(Event Storming)源自领域驱动设计社区,由 Alberto Brandolini 在2012 年发明[1]。 事件风暴最早的名字是基于事件的建模(Event-Based Modeling),正如这个名字所暗示的,事件风暴在发明之初的核心目的是领域建模,在今天的大多数文献和实践中,事件风暴的核心关注点都是领域模型和软件架构。
3775 2
基于事件风暴的需求分析 | 方法案例一
|
2月前
|
人工智能 大数据
碰撞事件探究
【10月更文挑战第21天】碰撞事件是一个充满奥秘和挑战的研究领域。深入理解碰撞的原理和规律,不仅有助于我们解决实际问题,也能让我们更好地认识自然界的运行机制。随着科学技术的不断进步,我们对碰撞事件的研究将不断深入,为人类的发展和进步提供更多的知识和启示。还可以结合具体的实验案例、实际应用和科学发现,进一步拓展和丰富对碰撞事件的探讨,使其更加全面和深入。
42 0
|
2月前
《从生产者消费者问题到高级解决方案的全方位解读&探究虚假呼唤现象》
《从生产者消费者问题到高级解决方案的全方位解读&探究虚假呼唤现象》
31 0
|
4月前
|
C#
由浅入深理解C#中的事件
由浅入深理解C#中的事件
114 19
|
4月前
|
Java Spring 供应链
Spring 框架事件发布与监听机制,如魔法风暴席卷软件世界,开启奇幻编程之旅!
【8月更文挑战第31天】《Spring框架中的事件发布与监听机制》介绍了Spring中如何利用事件发布与监听机制实现组件间的高效协作。这一机制像城市中的广播系统,事件发布者发送消息,监听器接收并响应。通过简单的示例代码,文章详细讲解了如何定义事件类、创建事件发布者与监听器,并确保组件间松散耦合,提升系统的可维护性和扩展性。掌握这一机制,如同拥有一把开启高效软件开发大门的钥匙。
53 0
|
5月前
|
运维 监控 安全
软件研发核心问题之用在需求拆解时明确监控范围与形式的问题如何解决
软件研发核心问题之用在需求拆解时明确监控范围与形式的问题如何解决
|
监控 项目管理
通俗易懂的方式理解项目管理的49个过程(追妹子案例)
通俗易懂的方式理解项目管理的49个过程(追妹子案例)
154 0
|
监控 前端开发
揭秘跨部门沟通的秘密武器:让不归你管的人主动配合你的绝妙方法!
揭秘跨部门沟通的秘密武器:让不归你管的人主动配合你的绝妙方法!
126 0
|
存储 NoSQL 算法
线上真实排队系统重构案例分享——实战篇
线上真实排队系统重构案例分享——实战篇
576 0
|
定位技术
事件风暴过程全体验-上篇
事件风暴过程全体验-上篇
事件风暴过程全体验-上篇