普通片儿 —— 起步价2¥,超过2天的部分每天每部电影收费1.3元
新片儿 —— 每天每部3元
儿童片 —— 起步价2¥,超过3天的部分每天每部电影收费0.8元
积分计算规则:
每借一部电影积分加1,新片每部加2
原始代码
程序结果:(请保证重构后结果不变~)
类图
有兴趣的可以先看看原始代码,考虑一下其中的原始对象关系,再行考虑如何重构代码。原始代码其实是有很多问题可以挖掘的,下面是我们的讨论整理:
划分职责关系,遵循单一职责原则
statement打印账单函数承担了很多功能,包括收费计算,积分计算以及结果展示等等
解法1: 6.1 Extract Method(提炼函数) —— 最常用的重构手法
解法2: 9.1 Decompose Conditional(分解条件表达式)
用户类中承担了不属于它的职责,包括:收费规则、积分规则。这些职责应该是属于电影类型的。
整理清楚其中的业务逻辑,比如收费规则和积分规则 - 见故事场景
不要直接访问对象的数据。容易发生其他对象改变该对象的数据,而拥有该数据的对象却一无所知。
解法:8.10 Encapsulate Field(封装字段手法) —— 使数据和行为想分离
重构不应该被外界所感知,保证testcases依然可行
部分重构
这里为了更好的展示重构的手法,使用TS,根据上面的讨论进行了部分重构,重构的方式其实是根据业务未来的扩展方向而定,并没有最优解,有兴趣的可以加入我们,抛出你的见解~
CODEPEN 执行结果:
重构后的类图关系
基本技巧
小步前进,频繁测试(保证足够的测试来支持你的重构行动)
使用智能开发工具(比如VSCode右键可以将过长的函数代码拆解函数化)
推荐书籍