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

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

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


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

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),正如这个名字所暗示的,事件风暴在发明之初的核心目的是领域建模,在今天的大多数文献和实践中,事件风暴的核心关注点都是领域模型和软件架构。
4641 2
基于事件风暴的需求分析 | 方法案例一
|
小程序 前端开发 程序员
不得不说,这19个程序员兼职平台让我1年收入60w
关于程序员接私活,社会各界说法不一。
2078 1
|
测试技术 领域建模 数据安全/隐私保护
运用事件风暴进行领域分析建模
运用事件风暴进行领域分析建模
运用事件风暴进行领域分析建模
|
8月前
|
人工智能 搜索推荐 IDE
MCP 是什么?一文看懂模型上下文协议
MCP(模型上下文协议)由Anthropic于2024年推出,旨在解决AI大模型的数据滞后问题,通过连接第三方数据源提升回答的时效性和相关性。传统联网搜索依赖公开信息,难以满足行业内部或定制化需求。MCP提供统一标准,使开发者能安全双向连接数据源与AI工具,简化集成流程。例如,Apifox MCP Server可将API文档作为数据源提供给支持MCP的IDE,助力智能代码生成。未来,MCP有望推动AI工具从封闭系统转向开放协作网络,显著提升开发效率与创新能力。
|
存储 关系型数据库 MySQL
深入解析MySQL数据存储机制:从表结构到物理存储
深入解析MySQL数据存储机制:从表结构到物理存储
1503 1
|
传感器 算法 机器人
基于 IMU 的位姿解算
解算 IMU 采样数据的过程与惯导解算技术原理有关,而提高定位精度的方法主要依赖于IMU自身精度的提高和算法改进。
1971 0
|
编解码 图形学 Android开发
事件风暴:领域驱动设计的实践
事件风暴:领域驱动设计的实践
|
安全 Dubbo 应用服务中间件
Sentinel 2.0 微服务零信任的探索与实践
Sentinel 2.0 微服务零信任的探索与实践
950 85
|
存储 人工智能 数据处理
Claude 3有哪些特点?
【2月更文挑战第17天】Claude 3有哪些特点?
800 2
Claude 3有哪些特点?