DDD 指的是 Domain-driven design(领域驱动设计),这套理论讲述的是如何在业务开发中建立业务模型,本文介绍最基本的实体和值对象概念。
从属性系统说起
以电商中的属性系统为例,搜索 iPhone 会展示很多筛选属性。机身内存 ROM、网络类型是「属性」,512G、256G、无需合约版、TD_LTE 是「属性选项」。表示为结构化的数据结构就是
{
"rom":[512, 256, 128],
"net_type": ["无需合约版", "TD_LTE"]
}
属性和属性系统应该如何存储到数据库中。一种方式是把属性和属性选型放在商品表的一个字段中。
商品 ID | 商品名 | 属性 |
---|---|---|
1001 | iPhone12 | 大小:512G,颜色:白 |
1002 | Huawei | 大小:256G,像素:1 亿 |
1003 | Xiaomi3 | 屏幕材质:OLED,尺寸:200 寸 |
如果属性和属性选项只是用来展示,这样存完全没有问题。但现在有这样的需求场景:
- 把商品中属性「屏幕材质」的名称修改为「屏幕材料」
- 用户搜索时,展示所有内存大小为 512G 的手机
第一个场景需要替换所有记录中的字段名称,第二个场景很难高效检索出来。这个时候就需要采用一种新的设计方式:
给属性新增自增标识符属性 ID,需要关联的地方使用属性 ID。
属性 ID | 属性名 |
---|---|
50001 | 颜色 |
50002 | 屏幕材质 |
50003 | 尺寸 |
给属性选项新增自增标识符属性选项 ID,需要关联的地方使用属性选项 ID。
属性选项 ID | 属性选项名 | 属性 ID |
---|---|---|
3001 | 白 | 50001 |
3002 | 黑 | 50001 |
3003 | OLED | 50002 |
3004 | LED | 50002 |
3005 | 512G | 50003 |
3006 | 256G | 50003 |
这样商品存储就变成了:
商品 ID | 商品名 | 属性选项 |
---|---|---|
1001 | iPhone12 | 3005, 3001 |
1002 | Huawei | 3005, … |
1003 | Xiaomi3 | 3003, … |
通过新增唯一标识符的方式,可以解决以上两个问题。当字段名修改时,由于表中关联的是 ID,所以无需改动。针对第二种场景一般使用搜索引擎,给属性选项字段建立倒排索引,这样就能实现高效检索。
值对象与实体
在 DDD 中第一种表示叫值对象,第二种叫实体。他们的区别是,实体拥有唯一标识符(主键 ID),且标识符在经过任何变化后仍然保持不变。对于这种实体,它其中的属性可以发生改变。而实体标识符的延续性会带来系统设计上的好处,以不变应万变。