背景
在团队的开发过程中,经常会听到 “xxx,代码写得真烂” 等等一系列话语,或者在 code review 的过程中针对你写的代码提出的一些挑战。那么本专栏就是结合自己在开发过程中碰到的问题来尽可能地避免这些问题。
曾经自己也被别人喷过无数遍的“代码写得烂”,即使被喷,也不要气馁,要相信大神都是被虐出来的。
就像打游戏,无论是《星际争霸》,《魔兽争霸 3》还是《英雄联盟》和《王者荣耀》,打得菜就会被喷。被喷是别人帮助你发现问题的方式。被喷没关系,重要的是被喷之后的自我总结和不断练习的过程。
代码的评判标准(什么是“烂代码”)
其实评判的标准有很多,而且评判的标准比较主关,下面我结合自己的开发经历梳理了最重要的几个标准。
可扩展性
定义: 对一段代码的修改,可以在不引入新的 Bug 和不破坏原有代码设计的情况下,做到又快速又安全。
个人的理解:
- 整体代码遵循“开闭原则”,即对扩展开放,对修改关闭。
- 需要面向接口编程,而不是面向实现编程。在写代码时,需要刻意思考一下,今后在一块要进行扩展,是否要预留一些扩展点(接口)。
可读性
定义: 对一段代码的阅读和理解,可以又快速又轻松地完成。提高别人阅读你代码逻辑的效率。
个人的理解:
- 遵循某一些编码规范,比如《阿里巴巴 Java 编程规约》。
- 在设计代码时,不要过度设计,不要为了一个不可能扩展的功能点而引入设计模式。
可复用性
定义: 整个工程代码中不出现重复的代码。
个人的理解:
- 要遵循单一职责原则,每个方法只做一件事。
- 利用好继承和多态的特性,引入模版方法模式,将公用的逻辑提取到抽象类中。
可测试性
定义: 可以非常方便地根据要测试的代码写出单元测试。
个人的理解:
- 利用好门面模式,对于要测试的方法,在设计代码时,需要提供一个入口。这样在写单元测试时,不需要写很多代码。
其他
因为评判代码的标准比较主观,其实还有很多其他标准,但是我觉得其他的标准也已经包含在上述原则之中了。
下面举几个例子:
- 灵活性:包含了,可复用性,可扩展性和可读性
- 简洁性:包含了,可读性
- 可维护性:包含了,可扩展性,可读性,可测试性,可复用性
如何提高代码质量
我从以下几方面进行举例:
面向对象
其实之前自己做了多年的开发,对于面向对象的概念只是停留在书本中的概念。为什么会这样?因为我们大多数开发中,都是在框架中填代码。又因为业务代码往往是一个流程,用面向过程的方式(一把梭的方式)来实现更容易被大脑接收。也正是因为这样,大多数的开发者对于面向对象还是理解不深刻。
面向对象需要掌握的点:
- 面向对象的特性:封装,抽象,继承,多态
- 面向对象与面向过程的区别
- 面向对象的充血模型和面向的贫血模型
- 多用组合少用继承
- 面向接口编程而非面向实现编程
设计原则
设计原则在书本中说的比较抽象,之后在专栏中会以我自身在实际开发中碰到的例子进行具体讲解。这些原则只有结合自身的开发中遇到的例子才能真正的掌握。
常见的设计原则如下:
- 单一职责原则
- 开闭原则
- 里氏替换原则
- 接口隔离原则
- 依赖倒置原则
设计模式
设计模式无论在面试中和实际开发中被提到得最多,也算是一个热点问题。这里先把设计模式罗列一下:
创建型
单例模式,工厂模式,建造者模式和原型模式
结构型
代理模式,装饰器模式,桥接模式,适配器模式,门面模式,组合模式和享元模式
行为型
观察者模式,模版模式,策略模式,责任链模式,迭代器模式,状态模式,访问者模式,备忘录模式,命令模式,解释器模式,中介模式。
编码规约
编码规约具体可以参照《阿里巴巴 Java 编码规约》。
为什么需要规约?
其实很好回答,凡事都需要有一定的约束,其目的是限制熵增大。
因为想把一个事物的熵降低是需要付出代价的。那么编码规约的价值就在于,在代码的熵增大之前,进行有效的遏制。
代码重构
在技术需求和产品需求在不断的迭代下,当初的代码设计必然会出现一些解决不了的问题,或者处理的不够优雅的时候。此时,需要明确以下几个问题:
- 当前代码哪一块的代码特别不优雅?
- 当前代码解决不了哪些技术和产品需求?
- 如果不进行重构,继续编写下去,会造成什么问题?
以上几点的联系
当代码重构时,肯定是碰到了一些问题,那么需要将这些问题列举出来。通过面向对象编程思想的基本方法论,总结出设计原则,又根据设计模式将设计原则在代码中进行实现,在编写代码的过程中遵循一定的编码规约,最后在代码重构结束时,能解决当初列举的问题。
代码重构: 是动机,也是目的。
面向对象: 是一个基本方法论。
设计原则: 是由面向对象基本方法论总结出的处理通用问题的经验。
设计模式: 是设计原则的具体体现。
编码规约: 是保障代码可读性的一个手段。