从增删改查到事件溯源 - PHP
增删改查
如果你是一名 PHP 后端开发,增删改查(CRUD)对你来说,一定不陌生。简单来说,它是指对数据库进行增加,删除,修改,查阅基本操作。增删改查是面向数据库的一种建模方式。PHP 简直是为增删改查而生,它语法简单,无需编译,ORM 遍地开花,你可以快速地将数据库表和网页打通,从而实现增删改查功能。这种快感给人一种错觉,似乎这就是一个后端开发者的核心工作。
让我们用增删改查的思路,设计一个简单购物车:
数据库设计
增删改查的第一步必然是数据库设计。为便于演示,我们设计从简,省去了很多细节,所以千万不要将这种设计用于你的产品中。我们仅使用一个表 carts 来储存购物车商品。
演示
当产品 p-1(ID:1)被加入购物车时,在 carts 表中增添一条数据:
当产品 p-2(ID:2)被加入购物车时,在 carts 表中再次增添一条数据:
当产品 p-1(ID:1)被再次加入购物车时,更新 carts 表中相应数据:
当产品 p-2 被移除购物车时,删除 carts 表中对应数据:
购物车的内容被实时地记录在数据库中,这是增删改查的主要特征。
让我们再来看看另一种截然不同的思想。
事件溯源
事件溯源(Event Sourcing)是领域驱动设计(Domain Driven Design)设计思想中的架构模式之一。领域驱动设计是面向业务的一种建模方式。它帮助我们将注意点放回业务本身。
事件溯源的核心是事件,所有聚合(一种特殊的类)的状态源头来自于事件,所以它叫事件溯源。这里的事件叫做领域事件,与我们通常所讲的事件不同的是,领域事件是指领域专家所关心,业务过程中所发生的事情,它与业务息息相关。
让我们用事件溯源的思想来设计上文中的购物车。
使用领域事件
在购物车这个业务中,假设自己是一个用户的话,我们最感兴趣的几件事情是将商品加入购物车,将商品移除购物车以及对购物车进行结算。于是我们可以总结出几个领域事件。值得注意的是,领域事件都应该是过去式。
当产品 p-1(ID:1)被加入购物车时,在 events 表中增添一条事件数据:
当产品 p-2(ID:2)被加入购物车时,在 events 表中增添一条事件数据:
当产品 p-1 被再次加入购物车时,在 events 表中增添一条事件数据:
当产品 p-2 被移除购物车时,仍然在 events 表中增添一条事件数据:
购物车的内容以事件的形式记录了下来,事件只可追加,不可以删除或者改动。
读取购物车商品
当需要展示购物车内容时,重播 events 表中所储存的事件即可:
拥抱事件溯源
事件溯源要求开发者改变自己的传统的,以数据库设计为源头的思想,从业务开始分析问题。用其开发的系统不仅仅自带日志,而且可以以领域事件为中心来方便地排查问题,同时事件驱动建立的聚合模型也非常容易编写单元测试。
增删改查并非恶魔
需要补充的是,增删改查并非一无是处,相反,在适合它的领域,它是非常强大的。在一些领域,增删改查就是当前的业务。比如一个简单的 CMS,比如 IoT 项目中对数据的存储。
结语
本文转载自【何以解耦】:codedecoupled.com/php-to-ddd.html,如果你也对 TDD,DDD以及简洁代码感兴趣,欢迎关注公众号【何以解耦】,一起探索软件开发之道。