文章插图
这样做可以避免很多不必要的麻烦 , Command 和 Query 存在较大的区别 , 具体如下:
文章插图
回想开篇时提到的场景 , 完成应用层拆分,就不再为使用错组件而烦恼:
- CommandService 的 Repository 不使用缓存,仅操作数据库
- QueryService 的 Repository 可以使用缓存,以提升访问性能
1.引入“模板方法设计模式” 以达到核心逻辑的复用
- 抽象出 BaseCommandService 和 BaseQueryService 两个父类用于统一核心流程
- 子类实现 BaseCommandService 和 BaseQueryService 的抽象方法完成功能扩展
- 按规范定义 CommandService 和 QueryService 接口,通过注解完成相关配置
- 自动生成 Proxy 实现类,完成流程编排
模型层是系统的核心,它的设计直接影响整个系统的质量 。作为承接业务逻辑的核心,比较流程的实现策略包括:
- DDD 领域驱动设计,其核心是使用面向对象的高级特性(封装、继承、多态、组合等)来进行设计,非常适合复杂的业务场景 。其体现就是存在很多高内聚低耦合的对象组(聚合根) , 业务逻辑由这些小对象相互协作共同完成;
- 事务脚本 , 使用过程式思维,将数据操作编织到流程中,比较适合并不复杂的业务场景 。其体现就是存在很多“上帝 Service”,Service 中存在很多非常长的方法,业务逻辑由这些方法完成 。
从不同应用场景出发便可得到如下结论:
- Command 场景需要保障严谨的业务逻辑,通常复杂性偏高,所以DDD 是最优解
- Query 场景需要更灵活的数据组装能力作为支持,通常比较简单 , 所以 事务脚本 是最优解
将模型拆分为 Command 和 Query,具体如下:
文章插图
完成模型拆分后,新模型具有以下特征:
- Agg 也就是 DDD 中聚合根,主要用于处理复杂的 Command 逻辑,由具有大量业务操作的"富对象"构成;
- View 是标准的 POJO , 主要充当 Query 结果对象,典型的“贫血对象”,仅作为数据的载体,根据展示需求对数据进行组装;
- View 没有自己的 Repository , 只能依赖 CommandRepository 获取数据,Converter 组件负责将 Agg 模型转换为 View 模型 。
比如在电商的订单模块:
- 生单流程,由 Order 作为聚合根对内部 OrderItem 和 PayInfo 进行统一协调
- 订单列表页 , 只需展示 Order 和 User 信息
- 订单详情,需要展示Order、User、Address、OrderItem、PayInfo、Product等信息
此时,应该根据场景对模型进行拆分:
- OrderBO 以 DDD 方式进行建模 , 对外提供统一的业务操作,对内协调 OrderItem 和 PayInfo 等多个实体对象;
- OrderListVO 以 POJO 方式进行建模,属性中包含 Order 和 User 信息;
- OrderDetAIlVO 以 POJO 方式进行建模,属性中包括 Order、User、Address、OrderItem、PayInfo、Product 等信息;
当然,由于使用统一的 Repository 还需提供对应 VO 的 Converter:
- OrderListVOConverter 将 OrderBO 转换为 OrderListVO 对象
- OrderDetailVOConverter 将 OrderBO 转化为 OrderDetailVO 对象
仓库层拆分也是非常有必要的,在这一层主要有几项冲突:
文章插图
仓库拆分后整体架构如下:
推荐阅读
- 谷歌SEO外链优化指南:高质量外链平台选择与实操技巧
- 关键词优化与整站优化,究竟谁更胜一筹?一文解析,助你轻松掌握SEO秘籍
- 网站运营的好与坏主要决定因素是内容与seo优化
- 针对英文网站的优化方法与技巧
- 杨幂与赵丽颖,14年为顶流“明争暗斗”,终于要分出输赢了
- 电视剧收视率排行榜:《与凤行》跌至第二,第一收视高达2.335%
- 查尔斯与戴安娜亲姐姐约会照曝光,原来当年戴安娜才是“备胎”!
- 单钩子线与八字环的绑法 子线与八字环的绑法
- 总局公布收视率榜单:第一名无悬念,《追风者》挤进前三,《与凤行》倒数
- 金赛纶因酒驾退圈,1年后发与金秀贤贴脸照引猜疑,理由让人无语