从增删改查到事件溯源 - PHP

从增删改查到事件溯源 - PHP

增删改查

如果你是一名 PHP 后端开发,增删改查(CRUD)对你来说,一定不陌生。简单来说,它是指对数据库进行增加,删除,修改,查阅基本操作。增删改查是面向数据库的一种建模方式。PHP 简直是为增删改查而生,它语法简单,无需编译,ORM 遍地开花,你可以快速地将数据库表和网页打通,从而实现增删改查功能。这种快感给人一种错觉,似乎这就是一个后端开发者的核心工作。

让我们用增删改查的思路,设计一个简单购物车:

数据库设计

增删改查的第一步必然是数据库设计。为便于演示,我们设计从简,省去了很多细节,所以千万不要将这种设计用于你的产品中。我们仅使用一个表 carts 来储存购物车商品。

db-design.png

演示

当产品 p-1(ID:1)被加入购物车时,在 carts 表中增添一条数据:

demo-1.png

当产品 p-2(ID:2)被加入购物车时,在 carts 表中再次增添一条数据:

demo-2.png

当产品 p-1(ID:1)被再次加入购物车时,更新 carts 表中相应数据:

demo-3.png

当产品 p-2 被移除购物车时,删除 carts 表中对应数据:

demo-4.png

购物车的内容被实时地记录在数据库中,这是增删改查的主要特征。

让我们再来看看另一种截然不同的思想。

事件溯源

事件溯源(Event Sourcing)是领域驱动设计(Domain Driven Design)设计思想中的架构模式之一。领域驱动设计是面向业务的一种建模方式。它帮助我们将注意点放回业务本身。

事件溯源的核心是事件,所有聚合(一种特殊的类)的状态源头来自于事件,所以它叫事件溯源。这里的事件叫做领域事件,与我们通常所讲的事件不同的是,领域事件是指领域专家所关心,业务过程中所发生的事情,它与业务息息相关。

让我们用事件溯源的思想来设计上文中的购物车。

使用领域事件

在购物车这个业务中,假设自己是一个用户的话,我们最感兴趣的几件事情是将商品加入购物车,将商品移除购物车以及对购物车进行结算。于是我们可以总结出几个领域事件。值得注意的是,领域事件都应该是过去式。

当产品 p-1(ID:1)被加入购物车时,在 events 表中增添一条事件数据:

de-1.png

当产品 p-2(ID:2)被加入购物车时,在 events 表中增添一条事件数据:

de-2.png

当产品 p-1 被再次加入购物车时,在 events 表中增添一条事件数据:

de-3.png

当产品 p-2 被移除购物车时,仍然在 events 表中增添一条事件数据:

de-4.png

购物车的内容以事件的形式记录了下来,事件只可追加,不可以删除或者改动。

读取购物车商品

当需要展示购物车内容时,重播 events 表中所储存的事件即可:

read-product.png

拥抱事件溯源

事件溯源要求开发者改变自己的传统的,以数据库设计为源头的思想,从业务开始分析问题。用其开发的系统不仅仅自带日志,而且可以以领域事件为中心来方便地排查问题,同时事件驱动建立的聚合模型也非常容易编写单元测试。

增删改查并非恶魔

需要补充的是,增删改查并非一无是处,相反,在适合它的领域,它是非常强大的。在一些领域,增删改查就是当前的业务。比如一个简单的 CMS,比如 IoT 项目中对数据的存储。

结语

本文转载自【何以解耦】:codedecoupled.com/php-to-ddd.html,如果你也对 TDD,DDD以及简洁代码感兴趣,欢迎关注公众号【何以解耦】,一起探索软件开发之道。

本作品采用《CC 协议》,转载必须注明作者和本文链接
Know how, know why meanwhile.
xuding
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 2
巴啦啦

购物车操作日志表+购物车表(id,user_id,product_id,num),这样看的话似乎业务逻辑能更简单。我记得老哥一直在做TDD,DDD的布道,我尝试着看过这两种开发方式,没有看太懂 :joy:

2年前 评论
xuding (楼主) 2年前

感觉跟 React 的时间旅行很像

2年前 评论
xuding (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!