课程大纲
第一部分 高质量编程
第一节 编程价值观
要编写出高质量的代码,就必须树立正确的编程价值观,从态度、习惯与技能三个方面端正对高质量代码的认识。
高质量代码体现了软件系统的内部质量,包括清晰、正确、可用、健壮、灵活和可维护这几个特征。
·清晰:意味着代码结构是清晰分明的,代码是可读而优雅的,能够很好地表达开发者的意图。
·正确:则意味着编写的功能满足客户需求,且尽可能避免出现缺陷。
·可用:意味着软件系统是正常可以运行的,不会因为用户的错误使用或者其他安全功能导致系统出现问题。
·健壮:则要求系统能够建立良好的容错功能,不会因为某个功能的错误而导致整个系统崩溃。
·灵活:则意味着程序设计的可扩展性好,可以很好地应对需求的变化。
·可维护:则意味着代码易于维护,易于扩展和修改,能够降低维护成本。
本部分内容将从正反两方面给出代码示例,通过对比的方式展现高质量代码的特征。
收益:
·统一认识,明确什么是高质量代码
第二节 编程方法论
如何写出高质量代码?这需要我们在提高编码技能的同时,以严谨的态度对待编程工作,反复推敲和修改代码。这部分内容主要讨论:
·编写可读的代码:代码可读性主要体现在命名、表达式与函数方面,对条件分支和异常的处理也是改善可读性的重要内容
·编写简单的代码:介绍简单设计的思想,引入案例,分析如何做到设计的恰如其分
·编写健壮的代码:从设计角度分析健壮代码的特征,分析常见错误和问题
收益:
·编写整洁代码
·实践简单设计
·提升代码的健壮性
第二部分 代码质量优化
第一节 重构的必要性
重构的目的是防止软件腐烂(Software rot)。软件腐烂也叫做代码腐烂(code rot)或软件腐朽(software decay)。它描述了随着时间的逝去感知到软件的缓慢衰退,其将最终导致它变得不完善、不可使用或难以维护。
本部分内容包括:
·介绍邮件转发器的真实案例说明什么是软件腐烂
·介绍重构的基本知识,讲解重构的基本思想和方法
·阐述重构对于软件工程的必要性
第二节 单元测试
如果没有覆盖率高的单元测试做保障,贸然进行重构是危险的。除了最基本的自动化重构可以在一定程度上无需测试保障之外,重构与测试尤其是单元测试都是相辅相成的。此外,如果我们掌握了编写单元测试的正确方法,它除了能够保证代码的质量外,还可以帮助我们改进设计。
本部分内容包括:
·明确单元测试的定义
·编写单元测试的FIRST原则
·编写单元测试的最佳实践
·单元测试的Given-When-Then模式
·单元测试框架JUnit
·单元测试的验证框架AssertJ
·Mock技术与Mockito框架
收益:
·掌握单元测试常用框架
·明确什么是正确的单元测试
第三节 代码坏味道
正如修复缺陷需要首先发现缺陷,要进行重构就需要首先学会如何识别代码的坏味道。所谓的“坏味道”,就是不好的代码,糟糕的代码,例如代码中出现大量的重复,命名不合理导致代码可读性差,方法和类庞大而臃肿,写出的代码极难理解。常见的坏味道分类包括:
·重复问题
·依赖纠结
·不稳定的结构
·僵硬的设计
·过度设计
·不必要的复杂度
收益:
·学会识别代码的坏味道
第四节 重构手法
正如医生识别出病症就要对症下药,当我们识别出代码的坏味道后,也需要使用对应的重构手法来改进代码的质量。当然,重构手法仅仅是一种方法,在重构过程中,我们还必须掌握基本的设计思想,明白什么才是好的代码,才能够在目标导向下去寻求重构的办法。因此本部分的培训会将重构手法与设计思想结合在一起,并通过实际案例让学员实际演练和操作,才能学会在自己的项目中正确地运用重构。
收益:
·了解IDE支持的重构手法
·通过完整案例演练重构
第三部分 领域驱动对象设计
第一节 对象的合理封装
对于对象的封装而言,我认为有两个步骤,可以帮助获得合理的封装。
首先是分辨职责,即弄清楚职责应该分配给什么对象。这个识别职责的过程同时也是寻找对象的过程。在这个步骤中,可以尝试用一句话来描述职责,只要你描述清楚了,则它应该依附的对象就应该自然而然显现。第二步则是判别哪些是实现细节,那些是可以公开的接口,以保证对细节的合理隐藏。暴露太多的细节可能会产生不合理的依赖,而从职责的角度来讲,这些细节并不是调用者所关心的内容。
对象的封装应该遵循信息专家模式与迪米特法则,又或者从代码层面,识别出的坏味道为Feature Envy。
案例分析:
·超市收银员的面向对象思想:对比版本1和版本2
收益:
·理解信息专家模式
·理解迪米特法则
·正确理解封装的价值
第二节 领域驱动战术设计模式
领域驱动设计的战术设计定义了自己的模式,包括实体、值对象、聚合、资源库、领域服务和领域事件等,同时规定了从领域分析建模、领域设计建模到最后实现建模的过程。在领域设计建模过程中,可以将领域驱动设计的设计要素与设计模式结合起来。
领域驱动设计的战术模式解决了理想化的对象设计问题,通过不同角色负责管理对象的生命周期、控制对象之间的协作与交互。
案例分析:
·超市收银员的DDD实现:对比版本2和版本3
·结算系统的DDD设计与实现:对比错误和正确的DDD设计
收益:
·理解领域驱动设计战术模式
·掌握遵循DDD的编程规则与实践
第三节 领域驱动战略设计模式
良好的设计还需要卓越的架构支持,通过定义清晰的架构单元,维护架构单元的边界,以确定每个架构单元的职责和对外公开的接口,可以有效地控制架构单元之间的协作。领域驱动设计通过在战略设计引入限界上下文与上下文映射,构成领域驱动架构的基础,同时,为限界上下文引入菱形对称架构模式,以保证代码模型的一致性,并有效地应对需求变化,打造可持续演进的应用架构。
案例分析:
·超市收银员的战略设计:对比版本3和版本4
·电商系统的订单流程:呈现架构层面的代码模型
案例演练:
·技术部落:根据业务需求识别限界上下文,绘制服务序列图
收益:
·理解限界上下文的概念
·限界上下文的角色构造型
·从架构层面规范设计与编码
第四部分 领域驱动编程实现
第一节 测试驱动开发
结合领域驱动设计中的服务驱动设计,以整洁代码、单元测试和重构为基础,全面介绍测试驱动开发。内容包括:
·测试驱动开发过程
·测试驱动开发三大定律
收益:
·了解什么是正确的测试驱动开发
·了解正确的测试驱动开发过程
第二节 服务驱动设计
通过识别业务服务,结合领域驱动设计和职责驱动设计,以业务服务为设计起点,明确职责分配的角色构造型,通过任务分解来划分职责层次,形成一种固化的设计过程,降低设计难度,提高设计质量。
案例分析:
·薪资结算:讲解如何运用服务驱动设计实现各种员工类型的薪资结算流程,改进设计质量
案例演练
·技术部落:针对业务需求开展领域建模,直至输出该需求对应的伪代码
收益:
·通过服务驱动设计规避贫血模型与事务脚本
·融合领域建模方法与战术模式
第三节 搭建开发框架
·要真正推进领域驱动设计方法的落地,除了需要掌握领域驱动设计的战略模式和战术模式之外,还要了解必要的开发框架,包括:
·ORM框架:讲解遵循JPA规范的ORM框架,使其与Repository的实现保持一致
·事务框架:讲解本地事务与分布式事务的主流框架,探讨如何在领域驱动设计背景下支持事务
·微服务框架:将限界上下文映射为微服务后,结合菱形对称架构和微服务框架,实现限界上下文之间的协作
·事件总线:如果在限界上下文之间引入事件,或者在聚合之间引入事件,该如何处理,该如何开展技术选型
·缓存:为了提升性能,引入本地缓存或分布式缓存,并将其与Repository结合起来
第四节 领域驱动开发演练
以一个完整的案例,结合服务驱动设计与测试驱动开发,进行领域驱动设计的开发演练。
收益:
·掌握领域驱动实现建模的过程,通过实践服务驱动设计与测试驱动开发,完成代码编写,同时提升研发质量