DDD学习笔记 - 实战篇(Ⅲ)

17 | 从后端到前端:微服务后,前端如何设计?

课程链接:https://time.geekbang.org/column/article/169017

 

微服务架构通常采用前后端分离的设计方式。作为企业级的中台,在完成单体应用拆分和微服务建设后,前端项目团队会同时面对多个中台微服务项目团队,这时候的前端人员就犹如维修电工一样了。

面对如此多的微服务暴露出来的 API 服务,如何进行正确的连接和拼装,才能保证不出错?这显然不是一件很容易的事情。而当服务出现变更时,又如何通知所有受影响的项目团队,这里面的沟通成本相信也不小。

相应的,要从一定程度上解决上述问题,是不是可以考虑先有效降低前端集成的复杂度呢?先做到前端聚合,后端解耦——这是一个很有意思的话题。一起来聊聊微前端(Micro Frontend)的设计思想,探讨一下中台微服务后,前后端的设计和集成方式。

 

单体前端的困境

传统企业在完成中台转型后,虽然后台的业务完成了微服务架构的升级,但前端仍然是单体模式,由一个团队创建并维护一个前端应用。随着时间推移和业务发展,前端会变得越来越臃肿,越来越难维护。而随着 5G 和移动互联技术的应用,企业业务活动将会进一步移动化和线上化。过去很多企业的做法是为不同的业务开发出独立的 APP。但很显然用户并不想装那么多的 APP!

为了提高用户体验,实现统一运营,很多企业开始缩减和整合 APP,将企业内所有的业务能力都尽量集中到一个 APP 中。试想如果仍然沿用单体前端的设计模式。前端项目团队将面对多个中台微服务团队,需要集成成千上万的 API 服务,这就需要相当高的沟通成本和技术要求。这绝对会是一场灾难。

相对互联网企业而言,传统企业的渠道应用更加多样化,有面向内部人员的门店类应用、面向外部客户的互联网电商平台或移动 APP,还有面向第三方的 API 集成。由于渠道的差异,前端将更加多样化和复杂化。那如何有效降低前端集成的复杂度呢?

 

从单体前端到微前端

为了解决单体前端的问题,可以借鉴微服务的设计思想,引入微前端概念。将微服务理念扩展到前端,解决中台微服务化后,前端由于仍为单体而存在的逻辑复杂和臃肿的问题。

在前端设计时需要遵循单一职责和复用原则,按照领域模型和微服务边界,将前端页面进行拆分。同时构建多个可以独立部署、完全自治、松耦合的页面组合,其中每个组合只负责特定业务单元的 UI 元素和功能,这些页面组合就是微前端。

微前端与微服务一样,都是希望将单体应用,按照规则拆分,并重组为多个可以独立开发、独立测试、独立部署和独立运维,松耦合的微前端或者微服务。以适应业务快速变化及分布式多团队并行开发的要求。

微前端页面只包括业务单元前端操作必需的页面要素,它只是企业级完整业务流程中的一个业务拼图块,不包含页面导航等内容。微前端除了可以实现前端页面的解耦外,还可实现页面复用,这也与中台服务共享理念是一脉相承的。

 

业务单元的组合形态

可以参照领域模型和微服务边界,建立与微服务对应的前端操作界面,将它与微服务组成业务单元,以业务组件的方式对外提供服务。业务单元包括微前端和微服务,可以独立开发、测试、部署和运维,可以自包含地完成领域模型中部分或全部的业务功能。

看一下下面这个图。一个虚框就是一个业务单元,微前端和微服务独立部署,业务单元内的微前端和微服务已完成前后端集成。可以将这个业务单元理解为一个特定业务领域的组件。业务单元可以有多种组合方式,以实现不同的业务目标。

1. 单一业务单元

一个微前端和一个微服务组成单一业务单元。微前端和微服务分别实现同一个领域模型从前端到后端的功能。

2. 组合业务单元

一个微前端与多个微服务组成组合业务单元。微前端具有多个微服务的前端功能,完成较复杂的页面和操作。多个微服务实现各自领域模型的功能,向微前端提供可组合的服务。记住一点:微前端不宜与过多的微服务组合,否则容易变成单体前端。

3. 通用共享业务单元

一个微前端与一个或多个通用中台微服务组合为通用共享业务单元。通用共享微前端以共享页面的方式与其它微前端页面协作,完成业务流程。很多通用中台微服务的微前端是共享的,比如订单和支付等微服务对应的订单和支付微前端界面。

所有业务单元的功能都应该自包含,业务单元之间的边界清晰。业务单元之间要避免功能交叉而出现耦合,一旦出现就会影响项目团队职责边界,进而影响到业务单元独立开发、测试、部署和运维等。

 

微前端的集成方式

看一下下面这个图,微前端位于前端主页面和微服务之间,它需要与两者完成集成。

1. 微前端与前端主页面的集成

前端主页面是企业级的前端页面,微前端是业务单元的前端页面。微前端通过主页面的微前端加载器,利用页面路由和动态加载等技术,将特定业务单元的微前端页面动态加载到前端主页面,实现前端主页面与微前端页面的“拼图式”集成。

微前端完成开发、集成和部署后,在前端主页面完成微前端注册以及页面路由配置,即可实现动态加载微前端页面。

2. 微前端与微服务的集成

微前端与微服务独立开发,独立部署。在微前端注册到前端主页面前,微前端需要与微服务完成集成。它的集成方式与传统前后端分离的集成方式没有差异。微服务将服务发布到 API 网关,微前端调用发布在 API 网关中的服务,即完成业务单元内的前后端集成。

 

团队职责边界

当采用业务单元化的开发方式后,前后端项目团队职责和应用边界会更清晰,可以降低前后端集成的复杂度。看一下前中台团队的职责分工。

前端项目团队专注于前端集成主页面与微前端的集成,完成前端主页面的企业级主流程的页面和流程编排以及微前端页面的动态加载,确保主流程业务逻辑和流程正确。前端项目除了要负责企业内页面风格的整体风格设计、业务流程的流转和控制外,还需要负责微前端页面动态加载、微前端注册、页面路由和页面数据共享等前端技术的实现。

中台项目团队完成业务单元组件的开发、测试和集成,确保业务单元内的业务逻辑、页面和流程正确,向外提供包含页面逻辑和业务逻辑的业务单元组件。

这样,前端项目团队只需要完成企业级前端主页面与业务单元的融合,前端只关注前端主页面与微前端页面之间的集成。这样就可以降低前端团队的技术敏感度、团队的沟通成本和集成复杂度,提高交付效率和用户体验。

中台项目团队关注业务单元功能的完整性和自包含能力,完成业务单元内微服务和微前端开发、集成和部署,提供业务单元组件。这样,业务单元的微前端与微服务的集成就会由一个中台团队完成,熟悉的人干熟悉的事情,可以降低集成过程中的沟通和技术成本,加快开发效率。

 

一个有关保险微前端设计的案例

保险公司有很多面向不同场景的保险产品,由于业务场景不同,其核心领域模型就会有差异,在页面要素、业务规则和流程等方面前端界面也会不同。为了避免领域模型差异较大的产品之间的相互影响和干扰,可以将相似的领域模型的保险产品聚合在一起,完成核心中台设计。

那有的保险集团为了统一运营,会实现寿险、财险等集团化的全险种销售。这样前端项目团队就需要用一个前端应用,集成非常多的不同产品的核心中台微服务,前端应用与中台微服务之间的集成将会更复杂。

如果仍然采用传统的单体前端模式,将会面临比较大的困难。

第一是前端页面开发和设计的复杂性。以录单前端为例,如果用一个前端页面来适配全险种,由于不同产品的前端页面要素不同,需要妥协并兼容所有产品界面的差异,这会增加前端开发的复杂度,也影响用户体验。而如果为每类产品开发不同的前端,前端项目团队需要在页面开发和设计上,投入巨大的工作量。

第二是前端与微服务集成的复杂性。在前端与微服务集成时,前端项目团队需要了解所有产品的 API 详细信息,完成前端与微服务的集成,还要根据主页面流程,实现不同产品的 API 服务路由。大量的 API 服务集成和服务路由,会增加系统集成的复杂度和出错的概率。

第三是前后端软件版本的协同发布。关联的应用多了以后,一旦某一个中台微服务的 API 服务出现重大调整,就需要协调所有受影响的应用同时完成版本发布,频繁的版本发布会影响不同产品的正常运营。

那如何用一个前端应用实现全险种产品销售呢?怎样设计才能降低集成的复杂度,实现前端界面融合,后端中台解耦呢?

看一下下面这个图。借鉴了电商的订单模式实现保险产品的全险种订单化销售,在一个前端主页面可以将所有业务流程和业务操作无缝串联起来。虽然后端有很多业务单元(包含微服务和微前端),但用户始终感觉是在一个前端应用中操作。

要在一个前端应用中实现全险种销售,需要完成以下内容的设计。

1. 微服务:微服务分为两类,一类是核心中台微服务,包括:投保微服务,实现核心出单业务逻辑;另一类是通用中台微服务,包括如:商品、订单、购物车和支付等微服务,实现通用共享业务逻辑。

2. 微前端:每个微服务都有自己的微前端页面,实现领域模型的微服务前端页面操作。核心中台投保微服务有出单微前端。订单、商品以及支付微服务都有自己的微前端页面。

3. 业务单元:微服务与微前端组合为一个业务单元。由一个中台团队完成业务单元的开发、集成、测试和部署,确保业务单元内页面操作和业务逻辑正确。比如:投保微服务和出单微前端组合为投保业务单元,独立完成保险产品从前端到后端的投保业务。

4. 前端主页面:前端主页面类似门户,包括页面导航以及部分通用的常驻主页面的共享页面,比如购物车。前端主页面和所有微前端应统一界面风格,符合统一的前端集成规范。按照正确的业务逻辑和规则,动态加载不同业务单元的微前端页面。前端主页面作为一个整体,协调核心和通用业务单元的微前端页面,完成业务操作和业务流程,提供全险种销售接触界面,包括商品目录、录单、购物车、订单、支付等操作。

5. 业务流程说明:简要说明一下用户在前端主页面的投保的主要业务流程。

  • 第 1 步:用户在前端主页面,从商品目录微前端页面,选择保险产品。
  • 第 2 步:前端主页面根据选择的产品,从主页面配置数据中,获取产品出单微前端路由地址。加载出单微前端页面,完成录单,投保微服务实现投保业务逻辑,在业务单元内生成投保单。
  • 第 3 步:加载购物车微前端,将投保单加入购物车。
  • 第 4 步:重复 1-3 步,生成多个投保单。
  • 第 5 步:从购物车微前端中选择多个投保单,加载订单微前端,生成订单。
  • 第 6 步:加载支付微前端,完成支付。
  • 第 7 步:在投保微服务中,将订单中的投保单生成保单。

虽然后端有很多业务单元在支持,但用户所有的页面操作和流转是在一个前端主页面完成的。在进行全险种的订单化销售时,用户始终感觉是在操作一个系统。这种设计方式很好地体现了前端的融合和中台的解耦。

 

总结

微前端和业务单元化的设计模式可以减轻企业级中台,前后端应用开发和集成的复杂度,真正实现前端融合和中台解耦。它的主要价值和意义如下:

1. 前端集成简单:前端项目只需关注前端集成主页面与微前端的集成,实现模块化集成和拼图式的开发,降低前端集成的复杂度和成本。

2. 项目职责专一:中台项目从数据库、中台微服务到微前端界面,端到端地完成领域逻辑功能开发,以业务组件的方式整体提供服务。在业务单元内,由团队自己完成前后端集成,可以降低开发和集成团队的沟通成本和集成复杂度。

3. 隔离和依赖性:业务单元在代码、逻辑和物理边界都是隔离的,可降低应用之间的依赖性。出现问题时可快速定位和修复,问题可以控制在一个业务单元内。业务单元之间相互无影响。

4. 降低沟通和测试成本:中台团队实现从微前端页面到中台微服务的业务单元逻辑,实现业务单元的开发、测试、集成和部署的全流程和全生命周期管理,降低前后端集成的测试和沟通成本。

5. 更敏捷地发布:业务单元之间有很好的隔离性和依赖性低,业务单元的变化都可以被控制在业务单元内。项目团队可以独立按照自己的步调进行迭代开发,实现更快的发布周期。版本发布时不会影响其它业务单元的正常运行。

6. 降低技术敏感性:前端项目关注前端主页面与微前端的集成。降低了前端项目团队对中台微服务技术的敏感性。中台项目团队可以更独立地尝试新技术和架构,实现架构的演进。

7. 高度复用性:微前端和中台微服务都有高度的复用性。微前端可快速加载到多个 APP,还可以将一个微前端直接发布为 APP 或微信小程序,实现灵活的前端组合、复用和快速发布。

 

======================================================================================================

 

18 | 知识点串讲:基于DDD的微服务设计实例

课程链接:https://time.geekbang.org/column/article/169881

 

从领域建模到微服务设计的全过程

项目基本信息

项目的目标是实现在线请假和考勤管理。功能描述如下:

1.请假人填写请假单提交审批,根据请假人身份、请假类型和请假天数进行校验,根据审批规则逐级递交上级审批,逐级核批通过则完成审批,否则审批不通过退回申请人。

2.根据考勤规则,核销请假数据后,对考勤数据进行校验,输出考勤统计。

 

战略设计

战略设计是根据用户旅程分析,找出领域对象和聚合根,对实体和值对象进行聚类组成聚合,划分限界上下文,建立领域模型的过程。

战略设计采用的方法是事件风暴,包括:产品愿景、场景分析、领域建模和微服务拆分等几个主要过程。

战略设计阶段建议参与人员:领域专家、业务需求方、产品经理、架构师、项目经理、开发经理和测试经理。

1. 产品愿景

产品愿景是对产品顶层价值设计,对产品目标用户、核心价值、差异化竞争点等信息达成一致,避免产品偏离方向。

事件风暴时,所有参与者针对每一个要点,在贴纸上写出自己的意见,贴到白板上。事件风暴主持者会对每个贴纸,讨论并对发散的意见进行收敛和统一,形成下面的产品愿景图。

把这个产品愿景图整理成一段文字就是:为了满足内外部人员,他们的在线请假、自动考勤统计和外部人员管理的需求,建设这个在线请假考勤系统,它是一个在线请假平台,可以自动考勤统计。它可以同时支持内外网请假,同时管理内外部人员请假和定期考勤分析,而不像 HR 系统,只管理内部人员,且只能内网使用。产品内外网皆可使用,可实现内外部人员无差异管理。

通过产品愿景分析,项目团队统一了系统名称——在线请假考勤系统,明确了项目目标和关键功能,与竞品(HR)的关键差异以及自己的优势和核心竞争力等。

产品愿景分析对于初创系统明确系统建设重点,统一团队建设目标和建立通用语言是很有价值的。但如果系统目标和需求非常清晰,这一步可以忽略。

2. 场景分析

场景分析是从用户视角出发,探索业务领域中的典型场景,产出领域中需要支撑的场景分类、用例操作以及不同子域之间的依赖关系,用以支撑领域建模。

项目团队成员一起用事件风暴分析请假和考勤的用户旅程。根据不同角色的旅程和场景分析,尽可能全面地梳理从前端操作到后端业务逻辑发生的所有操作、命令、领域事件以及外部依赖关系等信息。

下面以请假和人员两个场景作为示例。

第一个场景:请假

用户:请假人

  • 请假人登录系统:从权限微服务获取请假人信息和权限数据,完成登录认证。
  • 创建请假单:打开请假页面,选择请假类型和起始时间,录入请假信息。保存并创建请假单,提交请假审批。
  • 修改请假单:查询请假单,打开请假页面,修改请假单,提交请假审批。
  • 提交审批:获取审批规则,根据审批规则,从人员组织关系中获取审批人,给请假单分配审批人。

第二个场景:审批

用户:审批人

  • 审批人登录系统:从权限微服务获取审批人信息和权限数据,完成登录认证。
  • 获取请假单:获取审批人名下请假单,选择请假单。
  • 审批:填写审批意见。
  • 逐级审批:如果还需要上级审批,根据审批规则,从人员组织关系中获取审批人,给请假单分配审批人。重复以上 4 步。
  • 最后审批人完成审批。

完成审批后,产生请假审批已通过领域事件。后续有两个进一步的业务操作:发送请假审批已通过的通知,通知邮件系统告知请假人;将请假数据发送到考勤以便核销。

下面这个图是人员组织关系场景分析结果图,详细的分析过程以及考勤的场景分析就不描述了。

 

3. 领域建模

领域建模是通过对业务和问题域进行分析,建立领域模型。向上通过限界上下文指导微服务边界设计,向下通过聚合指导实体对象设计。领域建模是一个收敛的过程,分三步:

  • 第一步找出领域实体和值对象等领域对象;
  • 第二步找出聚合根,根据实体、值对象与聚合根的依赖关系,建立聚合;
  • 第三步根据业务及语义边界等因素,定义限界上下文。

下面逐步详细讲解一下。

第一步:找出实体和值对象等领域对象

根据场景分析,分析并找出发起或产生这些命令或领域事件的实体和值对象,将与实体或值对象有关的命令和事件聚集到实体。

下面这个图是分析后的实体与命令的关系。通过分析,找到了:请假单、审批意见、审批规则、人员、组织关系、刷卡明细、考勤明细以及考勤统计等实体和值对象。

第二步:定义聚合

定义聚合前,先找出聚合根。从上面的实体中,可以找出“请假单”和“人员”两个聚合根。然后找出与聚合根紧密依赖的实体和值对象。发现审批意见、审批规则和请假单紧密关联,组织关系和人员紧密关联。

找出这些实体的关系后,发现还有刷卡明细、考勤明细和考勤统计,这几个实体没有聚合根。这种情形在领域建模时会经常遇到,对于这类场景需要分情况特殊处理。

刷卡明细、考勤明细和考勤统计这几个实体,它们之间相互独立,找不出聚合根,不是富领域模型,但它们一起完成考勤业务逻辑,具有很高的业务内聚性。将这几个业务关联紧密的实体,放在一个考勤聚合内。在微服务设计时,依然采用 DDD 的设计和分析方法。由于没有聚合根来管理聚合内的实体,可以用传统的方法来管理实体。

经过分析,建立了请假、人员组织关系和考勤三个聚合。其中请假聚合有请假单、审批意见实体和审批规则等值对象。人员组织关系聚合有人员和组织关系等实体。考勤聚合有刷卡明细、考勤明细和考勤统计等实体。

第三步:定义限界上下文

由于人员组织关系聚合与请假聚合,共同完成请假的业务功能,两者在请假的限界上下文内。考勤聚合则单独构成考勤统计限界上下文。因此为业务划分请假和考勤统计两个限界上下文,建立请假和考勤两个领域模型。

 

4. 微服务的拆分

理论上一个限界上下文就可以设计为一个微服务,但还需要综合考虑多种外部因素,比如:职责单一性、敏态与稳态业务分离、非功能性需求(如弹性伸缩、版本发布频率和安全等要求)、软件包大小、团队沟通效率和技术异构等非业务要素。

在这个项目,划分微服务主要考虑职责单一性原则。因此根据限界上下文就可以拆分为请假和考勤两个微服务。其中请假微服务包含人员组织关系和请假两个聚合,考勤微服务包含考勤聚合。

到这里,战略设计就结束了。通过战略设计,建立了领域模型,划分了微服务边界。下一步就是战术设计了,也就是微服务设计。下面以请假微服务为例,讲解其设计过程。

 

战术设计

战术设计是根据领域模型进行微服务设计的过程。这个阶段主要梳理微服务内的领域对象,梳理领域对象之间的关系,确定它们在代码模型和分层架构中的位置,建立领域模型与微服务模型的映射关系,以及服务之间的依赖关系。

战术设计阶段建议参与人员:领域专家、产品经理、架构师、项目经理、开发经理和测试经理等。

战术设计包括以下两个阶段:分析微服务领域对象和设计微服务代码结构。

1. 分析微服务领域对象

领域模型有很多领域对象,但是这些对象带有比较重的业务属性。要完成从领域模型到微服务的落地,还需要进一步的分析和设计。在事件风暴基础上,进一步细化领域对象以及它们的关系,补充事件风暴可能遗漏的业务和技术细节。

分析微服务内应该有哪些服务?服务的分层?应用服务由哪些服务组合和编排完成?领域服务包括哪些实体和实体方法?哪个实体是聚合根?实体有哪些属性和方法?哪些对象应该设计为值对象等。

服务的识别和设计

事件风暴的命令是外部的一些操作和业务行为,也是微服务对外提供的能力。它往往与微服务的应用服务或者领域服务对应。可以将命令作为服务识别和设计的起点。具体步骤如下:

  • 根据命令设计应用服务,确定应用服务的功能,服务集合,组合和编排方式。服务集合中的服务包括领域服务或其它微服务的应用服务。
  • 根据应用服务功能要求设计领域服务,定义领域服务。这里需要注意:应用服务可能是由多个聚合的领域服务组合而成的。
  • 根据领域服务的功能,确定领域服务内的实体以及功能。
  • 设计实体基本属性和方法。

另外,还要考虑领域事件的异步化处理。

提交审批这个动作为例,来说明服务的识别和设计。提交审批的大体流程是:

  • 根据请假类型和时长,查询请假审批规则,获取下一步审批人的角色。
  • 根据审批角色从人员组织关系中查询下一审批人。
  • 为请假单分配审批人,并将审批规则保存至请假单。
  • 通过分析,需要在应用层和领域层设计以下服务和方法。

应用层:提交审批应用服务。

领域层:领域服务有查询审批规则、修改请假流程信息服务以及根据审批规则查询审批人服务,分别位于请假和人员组织关系聚合。请假单实体有修改请假流程信息方法,审批规则值对象有查询审批规则方法。人员实体有根据审批规则查询审批人方法。下图是分析出来的服务以及它们之间的依赖关系。

服务的识别和设计过程就是这样了,再来设计一下聚合内的对象。

聚合中的对象

在请假单聚合中,聚合根是请假单。

请假单经多级审核后,会产生多条审批意见,为了方便查询,可以将审批意见设计为实体。请假审批通过后,会产生请假审批通过的领域事件,因此还会有请假事件实体。请假聚合有以下实体:审批意见(记录审批人、审批状态和审批意见)和请假事件实体。再来分析一下请假单聚合的值对象。请假人和下一审批人数据来源于人员组织关系聚合中的人员实体,可设计为值对象。人员类型、请假类型和审批状态是枚举值类型,可设计为值对象。确定请假审批规则后,审批规则也可作为请假单的值对象。请假单聚合将包含以下值对象:请假人、人员类型、请假类型、下一审批人、审批状态和审批规则。

综上,就可以画出请假聚合对象关系图了。

在人员组织关系聚合中,可以建立人员之间的组织关系,通过组织关系类型找到上级审批领导。它的聚合根是人员,实体有组织关系(包括组织关系类型和上级审批领导),其中组织关系类型(如项目经理、处长、总经理等)是值对象。上级审批领导来源于人员聚合根,可设计为值对象。人员组织关系聚合将包含以下值对象:组织关系类型、上级审批领导。

综上,又可以画出人员组织关系聚合对象关系图了。

微服务内的对象清单

在确定各领域对象的属性后,就可以设计各领域对象在代码模型中的代码对象(包括代码对象的包名、类名和方法名),建立领域对象与代码对象的一一映射关系了。根据这种映射关系,相关人员可快速定位到业务逻辑所在的代码位置。在经过以上分析后,在微服务内就可以分析出如下图的对象清单。

2. 设计微服务代码结构

根据 DDD 的代码模型和各领域对象所在的包、类和方法,可以定义出请假微服务的代码结构,设计代码对象。

应用层代码结构

应用层包括:应用服务、DTO 以及事件发布相关代码。在 LeaveApplicationService 类内实现与聚合相关的应用服务,在 LoginApplicationService 封装外部微服务认证和权限的应用服务。

这里提醒一下:如果应用服务逻辑复杂的话,一个应用服务就可以构建一个类,这样可以避免一个类的代码过于庞大,不利于维护。

领域层代码结构

领域层包括一个或多个聚合的实体类、事件实体类、领域服务以及工厂、仓储相关代码。一个聚合对应一个聚合代码目录,聚合之间在代码上完全隔离,聚合之间通过应用层协调。

请假微服务领域层包含请假和人员两个聚合。人员和请假代码都放在各自的聚合所在目录结构的代码包中。如果随着业务发展,人员相关功能需要从请假微服务中拆分出来,只需将人员聚合代码包稍加改造,独立部署,即可快速发布为人员微服务。到这里,微服务内的领域对象,分层以及依赖关系就梳理清晰了。微服务的总体架构和代码模型也基本搭建完成了。

 

后续的工作

1. 详细设计

在完成领域模型和微服务设计后,还需要对微服务进行详细的设计。主要设计以下内容:实体属性、数据库表和字段、实体与数据库表映射、服务参数规约及功能实现等。

2. 代码开发和测试

开发人员只需要按照详细的设计文档和功能要求,找到业务功能对应的代码位置,完成代码开发就可以了。代码开发完成后,开发人员要编写单元测试用例,基于挡板模拟依赖对象完成服务测试。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1 您还未登录,请先 登录 后发表或查看评论
相关推荐

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页

打赏作者

Haozz_1994

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值