当前位置: 首页 > ds >正文

《小型支付商城系统》学习记录

1. MVC框架

2. DDD思想

3. MVC —> DDD重构

3.1 为什么要重构呢?

MVC旧工程随着业务的扩展,项目在不断地迭代更新,整个项目越来越庞大,业务越来越复杂,导致了MVC工程的腐化严重,迭代成本太高。

所以,希望借助DDD的设计思想,将MVC的工程重构,以便改善MVC工程的现状。

3.2 详解MVC工程的腐化

在普通的MVC中,一般主要包括三个部分:DAO、Domain、Service。这里的domain一般称为贫血对象,即只有对象没有逻辑,真正的逻辑是在Service中实现的,可能包括:po、vo等对象。这样的结构可能存在以下问题:“裤子乱穿”:当第一个对象定义好po、vo对象之后,另一个对象想使用时,发现已有的po、vo能够满足使用需求,就直接拿来使用。又一个对象想使用时,发现现存的po、vo基本可以满足需求,但是需要在此基础上进行适当扩展。别的对象想要调用时,也是同样的方式,这样随着对象的逐渐增多,就会导致交叉调用越来越混乱,po、vo对象也越来越复杂。就像是一条裤子,当第一个人做好之后,后边的人会将裤子拿来穿,但是发现不合适,就会进行加肥、加大,下一个人来穿,再进行加一些别的东西,这样就导致了这条裤子最后变得非常复杂。除此之外,在Service中,也会出现平行调用的情况,比如说某一个Service对象在实现业务逻辑时,发现别的Service已经实现该方法了,那么就直接将这个Service拿过来使用。并且,在Service中也不会区分业务功能和基础功能,比如说就是业务功能的Service会出现平行调用,同样比如说一些通用的功能如MQ消息、配置中心、缓存服务等,也会平行调用。这样就会使得整个结构非常混乱,在后期迭代更新、业务扩展时较为复杂。这样的工程架构对于小型的简单项目来说是适用的,开发速度较快,实现简单。但是对于长周期发展的项目来说,就会让项目后期的维护成本越来越高。

而DDD架构下,将domain这一层定义为充血模型,这里不仅仅是创建对象,还存在一些业务实现以及仓储逻辑。在这样的充血模型下,每个包和每个包之间是不存在任何关系的,是互相解耦的,没有任何依赖关系。并且,即使在初始阶段,某一个包下的功能另一个包下的功能很相似,也会去重新实现一遍,因为即使现阶段是相似的,但是随着业务功能的扩展以及后期的迭代更新,可能会不断地改变。所以,在domain充血模型下,是不存在平行调用的。

3.3 DDD思想下的分层结构

  • 应用封装 - app: 这是应用启动和配置的第一层,如一些 aop 切面或者 config 配置,以及打包镜像都是在这一层处理。你可以把它理解为专门为了启动服务而存在的。

  • 接口定义 - api:因为微服务中调用的 RPC 需要外提供接口的描述信息,也就是调用方在使用的时候,需要引入 Jar 包,让调用方好能依赖接口的定义。

  • 领域封装 - trigger: 触发器层,一般也叫做 adapter 适配器层。用于提供接口服务,消息接收,任务执行等。所以对于这样的操作,这里把它做触发器层。

  • 领域编排【可选】 - case: 领域编排层,一般对于较大且复杂的的项目,为了更好的防腐和提供通用的服务,一般会添加 case/application 层,用于对 domain 领域的逻辑进行封装组合处理。但对于一些小项目来说,完全可以去掉这一层。少量一层对象转换,代码的维护成本会降低很多。

  • 领域封装 - domain: 领域模块层,是一个非常重要的模块。无论怎样做DDD的分层架构,domain 都是必须存在的。在这一层中会有一个细分的领域服务,在每个服务包含各自【模型、仓库、服务】这样3部分。

  • 包含服务 - infrastructure: 基础层依赖于 domain 领域,因为存在对 domain 层定义的一些业务操作需要在这里实现。这是依赖倒转的一种设计方式。所有的仓库、接口、事件消息,都可以通过此处定义的方式进行调用。

  • 外部接入 - gateway: 对于外部接口的调用,也可以根据基础层定义一条 gateway 网关来进行 RPC/HTTP 等类请求的接入。

3.4 DDD分层调用链路

图中的下方是整个链路的调用关系。

3.5 设计模式的重要性

仅有DDD的设计思想是远远不够的,是不能提升代码质量的,想要提升代码质量必须合理使用设计模式再结合DDD的设计思想。

4. 需求PRD

需求,一般由产品给出,交由研发进行实现。

http://www.xdnf.cn/news/916.html

相关文章:

  • 测试模版1
  • 4.21总结
  • 思科路由器做DNS服务器
  • [数据可视化] Datagear使用心得:从数据整备到可视化联动实践
  • 基于Hadoop的音乐推荐系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 第二章 Logback的架构(一)
  • 电控---SWD协议
  • Spring Boot 断点续传实战:大文件上传不再怕网络中断
  • 240421 leetcode exercises
  • 堡垒机和跳板机之区别(The Difference between Fortress and Springboard Aircraft)
  • Docker 中将文件映射到 Linux 宿主机
  • C++算法(11):vector作为函数参数的三种传递方式详解
  • Vibracostic EDI 需求分析
  • 安卓的Launcher 在哪个环节进行启动
  • Cursor 配置中文界面并设置浅色背景的方法
  • 【云原生】k8s集群部署最新版ELFK日志采集平台
  • Qt-创建模块化.pri文件
  • Feign和Dubbo的技术选型对比分析
  • RK3588上编译opencv 及基于c++实现图像的读入
  • leetcode149.直线上最多的点数
  • 论文阅读HARIVO: Harnessing Text-to-Image Models for Video Generation
  • 在线查看网站免费工具 wps, dps, et, ett, wpt 文件格式
  • 【LeetCode】1.两数之和
  • 关于springmvc的404问题的一种猜测解决方案
  • Unity接入安卓SDK(2)接入方式
  • class com.alibaba.fastjson.JSONObject cannot be cast to class
  • Docker 镜像、容器和 Docker Compose的区别
  • 使用PyTorch实现图像增广与模型训练实战
  • 版本控制利器——SVN简介
  • SVN权限配置及连接指南