一、高质量编程
1、为什么存在这个话题?
(1)问题
在实际开发中,高质量编程大多数情况下难以实现。
一方面,大部分年轻的程序员开发经验少(初级程序员),写程序仅仅是满足设计文档上的功能性要求,离高质量程序相差甚远。
另一方面,程序员离最终用户距离较远,对程序上线后出现的很多问题并没有切身体会,无法编写出一些 看似稀奇古怪 却又合乎常理的需求。
(2)实际编码中的差异
【差异:】
对于同一个功能需求,高手 与 菜鸟 的差异将非常明显:
高手 代码量 会明显低于 菜鸟 的代码量。
高手 编码效率 会明显高于 菜鸟 的效率。
高手 代码性能 明显高于 菜鸟 的性能。
高手 代码可阅读性、安全性、可靠性 明显高于 菜鸟的代码。
注:
高质量编程 是每个优秀的程序员应该具备的。
每个程序员都经历过 菜鸟 的阶段,有的很快能够蜕变,而有的却一直无法改变,
那么如何令自己具备这种能力呢?
最重要的还是 培养自己的意识(学习优秀代码的思想,总结自己代码的不足)。
正所谓:学而不思则罔,思而不学则殆。
【程序员的变化:】
菜鸟:
能力:能够编写基本符合功能需求的程序。
态度:追求交差。
老手:
能力:能够长期稳定编写出高质量的程序。
态度:追求卓越。
高手:
能力:能够长期稳定编写出高质量、高难度的程序。
态度:追求完美。
2、高质量编程
(1)高质量编程具体是什么?
【高质量编程:】
可以从三个方面(编程风格、程序运行、后期拓展)来 描述 高质量编程。
编程风格:
整齐、简洁、易读。
程序运行:
正确运行、可靠、安全、高效、兼容
后期拓展:
可移植、可复用、可维护、可拓展。
(2)编程风格
【整齐:】
统一缩进:
通过缩进可以明确看出代码的层次结构。
合理分段:
可使用空行分隔 代码逻辑,将逻辑不紧密的代码隔开。
【简洁:】
减少冗余:
对于重复的代码,可以将其抽取成一个共通方法进行调用。
避免重复造轮子:
熟悉常用的库函数 以及 项目中自定义的 共同方法,避免重复编码(减少代码冗余)。
删除无用代码:
对于无用代码可以直接删除,无需在源文件中保留无用代码。
git、svn 等版本控制系统中会有历史提交记录,通过历史记录可以很方便的查看修改情况。
精简代码:
在保证解决需求的情况下,尽量优化代码,以较少的代码解决实际需求。
【易读:】
合理注释:
编写代码时添加上适当注释,方便 自己 或者 其他人 理解代码的含义。
合理命名:
根据命名规约,正确拼写。
合理规划项目结构:
使用合理的目录层次划分代码、文件,不同目录应具备不同的意义。
合理规划代码内部结构:
代码内部适当换行,避免 函数、代码 在一行上过长。
统一代码编写风格(比如:规定变量声明必须在函数或者方法第一行,避免在任意位置声明变量)。
(3)程序运行
【正确运行:】
满足基本需求:
能够满足基本设计需求。
满足默认规则:
满足有些属于软件常规操作但没有在设计中描述的需求。比如:TAB 键在页面上的顺序。
【可靠:】
持续稳定运行:
保证一些异常出现后,程序仍能正常运行(可以处理异常),不会崩溃。
并发安全:
保证程序并发执行时,系统内部执行逻辑不会出错。
无资源泄露:
持续工作时,不会出现内存溢出、内存泄露等不断消耗系统资源的问题。
【安全:】
完善日志处理:
对于核心操作,需要进行日志记录,确保修复 Bug 时可以快速定位错误位置。
保护敏感信息:
对于 用户密码 等敏感信息进行加密处理,不以明文方式进行保存。
防范常见攻击:
SQL 注入。
XSS 攻击(指的是 Cross Site Scripting,即 跨站脚本)。
CSRF 攻击(指的是 Cross Site Request Forgery,即 跨站请求伪造)。
【高效:】
循环代替递归:
递归资源消耗较大,尽量改为 循环实现。
精简循环代码:
循环无关代码 提取到 循环外,避免重复执行。
选取合适算法、数据结构:
根据数据特点,选取合适的数据结构以及算法 进行编码。
根据实际需求,尽量在 时间效率 以及 空间效率 上取得平衡。
发现并改善性能瓶颈:
比如采用 缓存机制 提高查询效率。
【兼容:】
确认程序运行环境:
使用兼容的 库函数 以及 API,保证程序在 各平台上兼容。
使用可兼容的组件:
为了保证可移植性,在技术选型时选择 具备良好兼容性的 组件、库函数 等。
(4)后期拓展
【可移植】
移植到不同的平台:
使用兼容性良好的组件、库函数等,通过较少修改保证程序正常运行。
资源独立:
进行国际化处理,保证 语言容易被提取、翻译、转换。
【可复用】
接口通用:
程序接口经过良好设计,具备通用性,不经修改即可用于其他系统。
【可维护】
完善日志机制:
根据日志信息定位错误地方,方便排查错误。
【可拓展】
良好程序结构:
定义良好程序结构,通过修改配置 或者 简单修改 即可应用 新添加的功能。
(5)如何实现高质量编程
【如何实现?】
编码前 需要仔细阅读 编码规约,保证编码风格一致(多人开发,风格难免有差异)。
编码时 需要不断自测,不能盲目自信(老子代码天下无敌 是不可取的)。
编码完成后 先自己思考一下能否继续优化,进一步可以请别人 来指点一下是否有更好的代码。
注:
要下意识的学习优秀代码的思想,总结自己代码的不足。
二、重构
1、为什么进行重构?
(1)举个例子
【举个例子:(仅供娱乐、参考)】
现有 A、B 两个人,A 向 B 提问:你的梦想是什么?
A 回答说:金钱和女人。
...
B 愣了一会儿说:这个答案有点肤浅了,请你重新组织语言,再次回答。
...
A 思考了一会后,回答说:事业和爱情。
注:
A 的两个回答,尽管表达的都是同一个意思,但是第二种回答 貌似比 第一种回答 更优雅一点。
这就是重构。
(2)代码重构
【代码的重构:】
在不改变代码原有功能的基础上,调整代码的内部结构,提高代码的可理解性,降低维护成本。
注:
代码重构后,基本功能肯定是与 原来的代码 一样的,
但是重构后,代码肯定优于 原来的代码,否则重构没有任何意义。
所以重构 是有一定的 难度的,需谨慎(开发一时爽、重构火葬场)。
【为什么进行代码的重构:】
不重构代码可能遇到的问题:
随着项目迭代、添加新功能,不同的开发人员进行 一系列 猛如虎的操作后,项目代码难免会臃肿、复杂、逻辑不清。
而这又导致项目难以理解、维护起来麻烦,增加了开发难度。
而进行重构后:
可以改进项目设计,给项目一个起死回生的机会(整理代码,使代码整体逻辑清晰)。
代码逻辑清晰后,便于阅读、理解代码,从而提高编程效率(排查 Bug 的效率也提高了)。
【重构的流程:】
Step1: 读懂代码,知道代码的功能。
Step2: 重构代码,保证原有功能。
Step3: 进行单元测试,保证代码原有功能不能消失。
2、重构时机
(1)什么时候需要重构?
对于首次开发的项目,经常会遇到重复性代码操作,此时就需要考虑是否进行重构,复用一些代码。
对于维护、迭代的项目,添加一个功能困难时,就得考虑是否需要进行重构,保证原有功能的基础上拓展新功能。
Debug 排错时,若不能一眼发现错误所在位置,就得考虑是否需要重构,使代码逻辑清晰。
代码审查时,若发现可以优化的代码,就得考虑是否需要重构,减少 BUG、提高执行效率。
(2)什么时候不能重构?
代码混乱、设计错误时,此时重构 将会带来很多问题,慎重重构。
代码发布期临近,重构会消耗大量时间时,慎重重构。
(3)需要重构代码的特征
【特征:】
重构很重要,那么如何重构?
当发现代码不对劲时,就说明需要重构了。
注:
此处不对劲指的是 代码可以被优化。
即需要重构的代码 具有某种可以被优化的特征。
比如:
重复代码。
类过大。
函数过长、函数参数列过长等。
【重复代码:】
重复代码指的是 在多个地方看到相同的代码段。
比如:
同一个类中存在两个以上相同代码段。
重构:
将代码抽取成一个共通方法,并调用。
【函数过长:】
函数过长指的是 很多功能均写在一个函数中,使函数变得复杂。
重构:
将函数中复杂的过程分解成若干个小函数。
注:
函数命名需要见名知意。最好做到 不阅读函数内部代码,仅通过函数名就能了解函数的功能。
函数功能最好单一,太复杂了可将其进行拆分。
......高质量编程当然不是这么简单说说就了事了。
吾日三省吾身,想要代码技术过硬,多学、多思考、多总结 是必备的。