设计原则与思想 --- 规范与重构

1.重构

Why - 重构的目的

重构是一种对软件内部结构的改善,目的是在不改变软件的可见行为的情况下,使其更易理解,修改成本更低。 —— Martin Fowler

理解核心:重构不改变外部的可见行为,即在保证功能不变的前提下,利用设计思想、原则、模式、编程规范等理论来优化代码,修改设计上的不足,提高代码质量。

What - 重构的对象

根据重构的规模,可以分为:

  • 大型重构:大规模、高层次的重构
    • 对象:对顶层代码设计的重构,包括:系统、模块、代码结构、类与类之间的关系
    • 手段:更多的利用 设计思想、原则、模式;比如:分层、模块化、解耦、抽象可复用组件
    • 影响:涉及代码改动多,影响面大,难度大,耗时长,风险大
  • 小型重构:小规模、低层次的重构
    • 对象:对代码细节的重构,包括:类、函数、变量等
    • 手段:更多的利用编码规范;比如:规范命名、规范注释、消除超大类或函数、提取重复代码
    • 影响:修改集中,比较简单,可操作性强,耗时短,风险小

When - 重构的时机

关键是具有持续重构意识,正确看待代码质量与重构,做到两不要:

  • 不要等到代码烂到一定程度,再去重构
  • 不要花尽心思去构思完美设计(避免开发初期过度设计),避免以后的重构

How - 重构的方法(技巧)

技巧1:代码可测试性

定义:【针对代码编写单元】测试的难易程度。编写可测性代码最有效手段:依赖注入

常见测试不友好的代码类型:(Anti-Patterns)

  • 代码中包含未决行为逻辑
  • 滥用可变全局变量
  • 滥用静态方法
  • 使用复杂的静态方法
  • 高度耦合的代码
技巧2:单元测试

单元测试并非要取代其他类型的测试,而只是缩小其他测试的范围;旨在检查代码的内部质量,专注于质量保证而非质量检查

保证代码质量的两个最有效的手段:单元测试 & Code Review!

ps:重构提升了软件质量,单元测试为重构提供了安全保障!

技巧3:解耦

解耦是大型重构最有效的一个手段!

当出现模块之间、类之间依赖复杂,出现“牵一发而动全身”,我们需要重构(解耦),解耦可以提高代码的可读性和可维护性,解耦保证代码松耦合、高内聚,是控制代码复杂度的有效手段。

如何解耦?

  • 封装与抽象
  • 添加中间层
  • 模块化
  • 设计思想与原则
    • 单一职责
    • 基于接口而非实现编程
    • 依赖注入
    • 多用组合少用继承
    • 迪米特法则
  • 设计模式
    • 观察者模式

2.编程规范(20条)

编程规范最重要一点:统一编程规范!!!

项目、团队,甚至公司,一定要制定统一的编码规范,并且通过 Code Review 督促执行,这对提高代码质量有立竿见影的效果。

命名与注释(Naming and Comments)

  • 命名长度:作用域小的变量(如临时变量)可以适当短一些,耳熟能详的缩写也可以。
  • 简化命名:可以借助类的信息来简化属性、函数的命名,利用函数的信息来简化函数参数的命名。
  • 命名需可读、可搜索:使用常用的英文单词命名。另外,命名要符合项目的统一规范。
  • 接口与抽象类的命名:
    • 接口有两种方式命名,一种是在接口中带前缀“I”,另一种是在接口的实现类中带后缀“Impl”。
    • 抽象类的命名,也有两种方式,一种是带上前缀“Abstract”,另一种是不带前缀。
    • 无论采用哪种,关键是要在项目中统一
  • 注释的目的:注释目的是让代码更容易看懂。只要符合这个要求,就可以将它写到注释里。注释的内容主要包含三个方面:做什么(功能)、为什么(目的)、怎么做(实现思路)。对于一些复杂的类与接口,可能还需要写明 如何用。
  • 注释的数量:注释本身有一定的维护成本,所以并非越多越好。类和函数一定要写注释,而且要写的尽可能全面、详细,而函数内部的注释要相对少一些,一般都是靠好的命名、提炼函数、解释性变量、总结性注释来提高代码可读性。

代码风格(Code Style)

  • 函数、类的大小尽量一屏幕看完,50行(类限制比较难确定);
  • 一行代码长度不要超过idea的显示宽度;
  • 为了函数逻辑更清晰,善用空行分割单元块(函数较长时);
  • 推荐二空格缩进大小,节省空间(尽量不要用tab键进行缩进);
  • 大括号可以紧接上一条语句同行,省代码行数;
  • 类中成员的排列顺序:依赖类按照字母序从小到大排列。类中先写成员变量,后写函数。成员变量之间或函数之间,先写静态成员变量或函数,后写普通变量或函数,并且按照作用域大小依次排列!(Google Java 编程规范)

编程技巧(Coding Tips)

  • 复杂的逻辑提炼拆分成函数和类(注:代码简单提炼,反而影响可读性)
  • 通过拆分多个函数(考虑职责单一)或将参数封装为对象的方式,来处理参数过多的情况
  • 函数中不要使用参数来做代码执行逻辑的控制(如:使用布尔类型的标识参数来控制内部逻辑,true 的时候走这块逻辑,false 的时候走另一块逻辑。这明显违背了单一职责原则和接口隔离原则。建议将其拆成两个函数,可读性上也要更好。)
  • 函数设计要职责单一
  • 移除过深的嵌套层次,方法包括:
    • 去除多余的 if 或 else 语句
    • 使用 continue、break、return 关键字,提前退出嵌套
    • 调整执行顺序来减少嵌套
    • 将部分嵌套逻辑抽象成函数
  • 用字面常量取代魔法数(设置常量,然后再函数中使用,不要直接在函数中使用 具体数字)
  • 用解释性变量来解释复杂表达式(比如 let bool = num > max, 然后将这个bool 带入函数中使用),以此提高代码可读性

参考

极客时间《设计模式之美》 ----- 王争

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这个月的砖不好搬

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值