知识卡片
优先设计值对象而非实体:不可变性带来的轻量与线程安全
内容
值对象是一把双刃剑:采用序列化大对象方式简化数据库设计、减少实体表数量,能简单清晰地表达业务概念,但代价是难以基于值对象内部属性做快速查询和统计分析(虽然越来越多数据库开始支持JSON字段查询,这个短板正在缓解);采用属性嵌入方式能提升数据库性能,但如果一个实体引用了过多值对象,实体上会堆积一堆缺乏概念完整性的零碎属性,值对象反而失去了它本该有的业务含义。抛开这些局限,值对象因为不可变性带来一个重要优势:它永远是正确的,不会在并发环境下被意外修改,因此可以被多个实体同时引用、安全地重用和共享,从而提升系统性能。基于这一点,书中给出一条设计建议:由于值对象比实体更轻量级、性能更高、线程更安全,一般应该优先把领域对象设计成值对象,而不是默认设计成实体,只有当这个对象确实需要唯一标识和跨状态变更的延续性时,才把它设计成实体——这是一条”默认选择更轻量方案,除非有明确理由才升级到更重的方案”的通用设计原则。
参考来源
- 位置:第7章《实体和值对象:领域模型的基础单元》"7.2 值对象","4. 值对象的优势和局限"(源文件:_epub-src/OEBPS/Text/chapter3-3-2.xhtml)
- 结论依据:原文说明"值对象的不可变性,确保了值对象永远都是正确的,在并发环境下不会被意外修改。所以在它同时被多个实体引用时,可以实现重用和共享,从而提高系统性能。鉴于值对象比实体更轻量级、高性能且线程安全,所以一般建议将领域对象优先设计为值对象,而非实体",直接支撑本卡片结论。
- 原始内容:值对象的不可变性,确保了值对象永远都是正确的,在并发环境下不会被意外修改。所以在它同时被多个实体引用时,可以实现重用和共享,从而提高系统性能。鉴于值对象比实体更轻量级、高性能且线程安全,所以一般建议将领域对象优先设计为值对象,而非实体。