优化代码中的“坏味道”
“ 一颗老鼠屎,坏了一锅粥,代码也是如此。”
在我们的项目中,也许在刚开始开发的时候,大家都会遵从一些规范来实施,但是当业务进度催的紧,或者人员变动,随着时间的迁移,项目不断的迭代以后,这时的代码可能就会出现一些“坏味道”了。
“坏味道”代码的出现可能不会影响我们的业务逻辑,大家自然也就比较容易忽视掉了,但是这如同是给我们代码埋下的定时炸弹,当爆炸的那天,需要我们背锅处理的时候,就会后悔当初为何不去解决这些问题呢?下面我们来看一下有哪些“坏味道”代码可以提前处理的吧。
1、多此一举型代码。
if(a > b){
return true;
}else{
return false;
}
也许一些经验不那么老道的开发会觉得这段代码没问题呀,可以跑得通,确实,在逻辑上是没问题的,但是有更简洁明了的写法为何不用?if() 里面的条件是boolean ,然后我们的返回值也是boolean,所以可以改写成
return a > b;
2、瞎命名型代码。
int a;
String wzbt; // 文章标题
String fastdi; //fast di 快递 。。中西结合...
以上只是不规范命名的实例的冰山一角,良好的命名除了见名知意以外,还可以在长时间以后回来阅读代码时,更快的回忆起业务逻辑,不至于在各种无解的命名中乱了手脚,为了一时的方便而随意命名是非常不值得的。
3、if完一定要加else型代码
if(condition){
//dosm
}else{
return ;
}
if(condition){
//dosm
}else{
throw new Exception();
}
while(xx){
if(condition){
//dosm
}else{
continue;
}
}
很多情况下,我们通过一些语句的前置类减少不必要的else,让代码看起来更简练清晰。
if(!condition){
return ;
}
//dosm
if(!condition){
throw new Exception();
}
//dosm
4、复制粘贴型
举个例子,项目中A模块引入B模块的优惠券业务,此时C模块也要引入B模块的优惠券业务,由于此时的优惠券业务可能是B模块中的几行代码,很多人就为了贪图方便,直接复制这几行代码直接放到C模块了。so easy,代码完美运行。
看起来似乎又没什么毛病,此时程序员的天敌产品经理过来了,他说在要在优惠券逻辑前面加点限制条件,ok,那么此时就要改动A模块跟B模块2份代码,而且要保持一致性,这个需求就完成了。过了一个版本,D模块也要引用优惠券业务,此时你又愉快的复制过去,然后可爱的产品经理又过来跟你说,这个版本我们要砍掉前面的限制条件...这时候你就要同步三段代码...跟产品经理的一场大战估计在所难免了。
所以从上面的案例中,如果我们一开始不偷懒把公共逻辑抽取出来,在各个模块引用的话,不论怎么修改,我们只要维护一份逻辑就可以,不至于手忙脚乱。
5、又长又臭型代码
此类坏味道代码一般出现在“有历史“的代码中,经过不同开发人员的迭代,一个方法可能会出现几千行的情况,即使有注释,也会让人看得痛不欲生,这时候刚接手修改的人必然会说一句“WTF”了。
所以这就要求我们在平时写代码的过程中养成提炼的习惯,一般来说,当某块业务逻辑需要注释来说明的时候,一般都可以提炼成方法来调用,通过这种方式会使得阅读代码的时候逻辑更加清晰。
还有一种又长又臭情况是出现在方法的参数中,不断的迭代过程也会导致参数的增加或者修改,甚至有看过朋友公司的代码出现一个方法10多个参数的情况。一般来说,当参数超过5个的时候就要考虑封装到对象当中了。
6、无病呻吟型
//输出info日志
logger.info("xxx");
//定义num变量
int num = 0;
...
上面举例的是一些无关痛痒的注释,当代码中充斥着这些玩意的时候会让人觉得很臃肿,当你做到上面五点的时候,代码已经不需要太多注释了(滑稽),所以我们的注释要注释到痛点,具体可参考《阿里java开发规范手册》
细节决定成败,在我们工作的过程中,当然还有很多需要我们注意的细节,大家有什么心得可以留言交流一下~
最后推荐一下 <重构 改善代码的既有设计>这本书,比较详细的介绍有那些坏味道需要重构的地方。
喜欢的话,劳烦关注一下微信公众号《深夜里的程序猿》噢~
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
复盘一次生产问题
有整整 10 天木有更文了,这段时间确实比较忙。 有加我微信的朋友知道我上周末出去春游了,部门组织去了趟外伶仃岛,环境挺不错的,这段时间去的人也比较少,值得去玩。 今天讲讲上周末一次生产问题的复盘。 1 事情经过 周日中午从外伶仃岛回来就直奔公司,因为生产出了些问题。问题是这样的:HBase 的一些节点挂了,导致一些数据丢失。丢失数据的客户来授信或者借款,都会卡件。在确定数据短时间没法恢复时,就决定从系统的层面去解决这个问题。这时我咨询了 2 位老员工,这些数据虽然是规则的入参数据,但是规则可能没用这些数据去做决策,能否先跟规则的同事确认这些数据是否有使用,如果没有,就可以先暂停这些数据的获取,减少影响面,再来细致的分析数据。得到的回复都是这些数据很早前就上线了,肯定有在用。这时只能分析系统数据,恰巧丢失的数据是原始数据,不是加工数据,原始数据不做规则入参,所以就简单的修改了获取数据源的代码。 在测试同事进行简单回归测试时,发现了一个奇怪的现象,旧数据被覆盖,检查了各种 SQL 配置,没有发现问题,因为以前也有很多模型和规则入参都是这样配置的,接着就陷入历史问题的 debug 中,还是...
- 下一篇
Netty Reactor模式实现原理详解
在前面的文章中(Reactor模型详解),我们讲解了Reactor模式的各种演变形式,本文主要讲解的则是Netty是如何实现Reactor模式的。这里关于Netty实现的Reactor模式,需要说明的是,其实现的模式如下图所示: 对于Netty使用的Reactor模式,其主要特点如下: 使用一个线程作为mainReactor,专门用于监听客户端的连接事件,当获取到事件之后就将该事件交由Acceptor处理,以获取客户端连接; 在mainReactor获取客户端Channel之后,将其交由subReactor进行处理,这里的subReactor是一个线程池。 subReactor会完成诸如客户端Channel注册,数据读取,业务计算,以及数据写入的工作。这里需要注意的是,对于特定的客户端Channel而言,这一系列处理都是与subReactor中某个特定的线程进行绑定的。 1. 用法示例 关于Netty的用法,这里我们还是使用TimeServer展示其最简单的一个使用示例: public class TimeServer { public void bind(int port) thro...
相关文章
文章评论
共有0条评论来说两句吧...