前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >重构方法与实践笔记

重构方法与实践笔记

原创
作者头像
Erossssssss
修改2021-07-05 09:56:20
8840
修改2021-07-05 09:56:20
举报
文章被收录于专栏:Eleanor的专栏Eleanor的专栏

1.代码的改写从大范围到小范围大致可以分为四级:系统级别,功能级别,代码级别,机器级别; 2.代码级别以下改动可视为“重构”,功能级别以上级别只能视为“重写”

3.重构是持续的日常过程,而重写不是

辨析了“重写”与“重构”之后,下面专注地讲一下重构

1.1 重构的概念和背景

  1. EPC
  2. 破窗理论与懒惰:在没有刻意优化下,代码腐烂是必然的
  3. 80%在别人的代码上进行修改

1.2 重构的目的:使软件结构更加合理

- 1.2.1 WHAT:

在不改变可观察行为下,修改代码内部结构

- 1.2.2 WHY:

差的设计在后期越来越难以新增功能,好的设计在软件开发的每个阶段新增功能的速度都是差不多的

- 1.2.3 WHEN:

童子军法则,只要修改完比修改后更易懂,大到设计,小到函数,命名

- 1.2.4 HOW :
-1.2.4.1 构建测试安全网
代码语言:txt
复制
	1. 使用单元测试;分层测试;UI自动化测试
	2. 进行可测试性改造:UI分离;Mock;依赖注入
- 1.2.4.2 消除代码坏味道
代码语言:txt
复制
	**1. - 函数问题(30s能读懂)**
代码语言:txt
复制
- 过长函数(Long Method):最好不超过20行
- 过长参数列(Long Parameter List):最好不超过5个《代码整洁之道推荐不超过3个》
- 基本类型偏执(Primitive Obsession)
- 重复的Switch(Repeat Switch)
- 循环问题(Loops)
2.单个类问题
代码语言:txt
复制
		- 过大的类(Large Class)
		- 临时字段(Temporary Field)
		- 数据泥团(Data Clumps):大量的数据要用结构组织,不要平铺
代码语言:txt
复制
		- 纯数据类 (Data Class)
		- 神秘命名(Mysterious Name)
		- 全局变量 (Global Data)
		- 可变数据 (Mutable Data)
- 3. 类关系
代码语言:txt
复制
		- 发散式变化(Divergant Change)
		- 散弹式修改(Shotgun Surgery)
		- 依恋情节(Feature Envy)
		- 夸夸其谈通用性(Speculative Generality)
		- 过长的消息链(Message Chain)
		- 中间人(Middle Man)
		- 内幕交易(Insider Trading)
		- 被拒绝的馈赠(Refuse Bequest)如子类不需要父类功能特性, **组合而不是继承**
- 4. 需要删除
代码语言:txt
复制
		- 注释(Comments): 代码自注释 > 写注释  > 不写注释
		- 重复代码(Duplicated Code)
		- 冗余元素(Lazy Element)
		- 异曲同工的类(Alternative Class with Defenter interface )
- 1.2.5 工具
代码语言:txt
复制
	- SonarLint 插件 + CodeDog
	- IDE Refactor  + Complex Method

2. 函数重构

2.1 工具

  • ApprovalTest + Coverage = 无脑单测
  • CombinationAppovals.verifyAllCombinations
  • Android Studio IDE 覆盖率设置 设置Tracing 格式的可以查看单测命中率 - Preference -> Coverage -> Replace active suites with the new one - Edit Configuration -> Junit -> Tracing

2.2何时重构?

  • 当你想要写注释时

2.3 大函数改造

  • Bloaters - Long Methodundefined维护者未必无法识别Bad Code Smell,重构难,懒惰心理等问题使得coder 躺平。 - 难以维护 - 容易出现bug - 破窗效应
  • 优秀函数的原则:
  • 函数一般写10行
  • 超过20行就考虑重构
    • 第一条规则是短小
    • 第二条规则还是短小
  • 如何处理条件语句
代码语言:txt
复制
- 函数提取:即按照逻辑拆分子函数。
- 分解表达式
- 以多态处理堆叠的条件表达式(如switch)
代码语言:txt
复制
	- 状态模式
	- 策略模式
代码语言:txt
复制
- 将条件表达式转换为查找表,使用注解完成映射

2.4 进阶优化

  • 组合函数(Composed Method)
代码语言:txt
复制
- 封装细节
- 保留关键函数路径
- 抽象层次一致
- 最好不要超过10行
- 函数自注释
  • 过长参数
代码语言:txt
复制
- 问题
代码语言:txt
复制
	- 调用参数不易传递
	- 增加理解难度
	- 伴随巨大函数,基本类型偏执
代码语言:txt
复制
- 解决方案
代码语言:txt
复制
	- 构造参数对象
	- 用builder 代替构造器
	- 卫语句,即异常case先返回,主要逻辑在后。将嵌套逻辑扁平化
	- 管道替代循环,声明式替代命令式

3. 类重构

Program to an interface, not an implementation.

组合优于继承

3.1 重构为啥难?

    1. 粘滞性
    1. 个人因素
代码语言:txt
复制
- 代码阅读能力
- 重构方法的掌握
    1. 环境因素
代码语言:txt
复制
- 时间,如需求倒排

3.2 面向对象

  • 3.2.1 三大特性
代码语言:txt
复制
- 抽象
- 继承
- 多态
  • 3.2.2 设计原则 使用接口进行解偶
代码语言:txt
复制
- 单一职责
- 接口设计
代码语言:txt
复制
	- 依赖倒置原则
	- 接口分离原则
	- 接口隔离原则
代码语言:txt
复制
- 一个类要尽可能不依赖外部
代码语言:txt
复制
	- 高内聚、低耦合
	- 开闭原则
	- 迪米特法则
代码语言:txt
复制
- 如何处理父子关系
代码语言:txt
复制
	- 里氏替换原则
	- 合成、聚合原则
  • 3.2.3 四个要素
代码语言:txt
复制
- 3.2.3.1 抽象:提取关键元素
代码语言:txt
复制
	- 三原则
代码语言:txt
复制
		- DRY 原则:Don't Repeat Yourself
		- YAGNI 原则:极限编程,不需要抽象那些你不需要的东西
		- Rule of three: 原则1,2的取舍方法
代码语言:txt
复制
	- 抽象不足
代码语言:txt
复制
		- God Project:违反了单一职责原则
代码语言:txt
复制
		  Android 刚开始开发时,使用MVC,V与C混杂在一起,造就了很多God Object。
代码语言:txt
复制
			- 提取类
代码语言:txt
复制
	- 抽象过度
代码语言:txt
复制
		- 如没有变量,只有方法,则抽象过于具体
代码语言:txt
复制
- 3.2.3.2 封装:隐藏细节
代码语言:txt
复制
	- 封装细节
代码语言:txt
复制
		- 1. 成员变量,一般设置为private
		- 2. 集合:Collections.unmodifiableList
		- 3. 函数:暴露较少接口,慎重写public函数
代码语言:txt
复制
	- 封装可预期变化
代码语言:txt
复制
		- 1. 散弹式修改,如每个AIDL调用,新增时非常复杂(使用查找表+注解依赖注入完成自动映射,不必每次新增)
代码语言:txt
复制
- 3.2.3.3 模块化
代码语言:txt
复制
	- 实现手法
代码语言:txt
复制
		- 通过封装得到模块
		- 模块之间使用接口交互
代码语言:txt
复制
	- 常见问题
代码语言:txt
复制
		- 模块接口异常
代码语言:txt
复制
			- 臃肿 如Refuse Bequest
			- 多变
代码语言:txt
复制
		- 模块依赖异常
代码语言:txt
复制
			- 循环依赖
代码语言:txt
复制
				- 修改一处,相互影响,产生震荡
				- 切断循环依赖
				- 继承可能也产生循环依赖
代码语言:txt
复制
			- 中间人依赖
代码语言:txt
复制
				- 依赖方个数 + 被依赖方个数越大,(一般)出现问题可能性越高。
代码语言:txt
复制
- 3.2.3.4 层次结构
代码语言:txt
复制
	- 常见问题
		- 继承关系复杂
		- 不恰当的继承(Stack -> vector ,不成立的继承关系)
代码语言:txt
复制
	- 解决方案
		- 确保可替换性
		- 组合优于继承
		- 依赖顺序正确,最好是层级次序
		- 继承结构简洁,如2层

推荐书籍

  • 重构
  • 设计模式
  • 代码整洁之道
  • 重构与模式

工程师素养

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1 重构的概念和背景
    • 1.2 重构的目的:使软件结构更加合理
      • - 1.2.1 WHAT:
      • - 1.2.2 WHY:
      • - 1.2.3 WHEN:
      • - 1.2.4 HOW :
      • - 1.2.5 工具
  • 2. 函数重构
    • 2.1 工具
      • 2.2何时重构?
        • 2.3 大函数改造
          • 2.4 进阶优化
          • 3. 类重构
            • 3.1 重构为啥难?
              • 3.2 面向对象
              • 推荐书籍
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档