-
解决思路
结构设计
操作示例
扩展方式
效果检视
总结
在某些复杂的业务场景下,开发者需要应对非常多的业务类,每种业务类均有较多的属性或者属性集,这些业务类又需要持久化到硬盘或者数据库,从领域驱动设计对于要素的拆分(值对象ValueObject
、实体Entity
、存储库Repository
),可以形成如下类图:
针对每种业务类T
,需要提取实体类接口IEntity
,同时提供持久化接口IRepository
. 为了支持测试和方便开发,首先会考虑提供内存版实现:
之后将开发完成的组件提供数据库适配,类关系图如下:
如果你有n
种业务类型,就需要n*(2+2+2)
,共n*6
个类.当然这是极限场景的情况,实际上Java
等语言都提供了ORM
,而且实体类也不一定需要提取接口,针对每种实体类可能会提供属性系统来使得实体类退化成普通的值对象.
上述设计基本上就是整洁架构或者说六边形架构倡导的方式.使用存储库接口IRepository
进行依赖倒置,并与特定数据源解耦. 由于其复杂性,在C++中采用相应方式工作量大,重复劳动也多,应用困难.那么有没有方法既能享受这种结构带来的益处,又无需付出太多编码成本呢?
解决思路
在游戏行业常用的Entity-Component-System
架构模式中,同样有实体Entity
概念,只不过值对象ValueObject
在这里被称为Component
,而且游戏通常是在内存中运行的,对于持久化需求不多,因而没有存储库Repository
概念.但是ECS
架构有一种观察问题的视角,这里的实体通常只是一个ID
,它认为实体就是由各种数据组件Component
组合而成,业务逻辑处理放在System
中,由此来解决类膨胀问题.
我们可以这样理解,之前为业务提供实体类,包含了唯一标识符、数据、业务逻辑,在ECS
中被拆分成三部分:Entity
、Component
、System
.这种组合式设计既能够充分利用已有的数据定义和业务逻辑,添加也非常容易,能够很方便地组合出新的业务类型,应对业务类膨胀和新的需求.
那么在设计中是否可以利用这样的思路,把实体视为值对象的组合,以数据组件Component
为最小单元进行设计,实体和存储库均在其上构建.通过C++语言强大的基于类型编程能力设计出组合式的结构来,增加复用可能性,减少代码量?