注: 以下内容引自http://blog.csdn.net/xtayfjpk/article/details/52136686

请注意写代码的习惯与态度(Java)

原创 2016年08月06日 16:05:17
  • 763

我相信很多人都有看别人代码的经历,我也相信很多人看过之后都在心里吐槽:这是哪个SB写的代码,还没有来得及看业务逻辑就因到处充斥着各种代码的“坏味道”,让你根本没信心能看懂这些代码,其导致的结果就是推倒重来。那么,不禁要问是什么原因导致了这种代码让人抓狂,无法理解;原因无非要么是技术水平的问题,要么是写代码的习惯与态度问题。由于大部分的项目业务逻辑并不会太复杂,所以在我看来,最大的原因来自写代码的习惯与态度。我也经常需要看以前别人写过的代码,特别是非全新项目,需求一改,就需要更新代码。当我看到这些代码是,感觉非常凌乱,有种无从看起的感觉。因为有太多的代码“坏味道”,所以本人想来总结一下代码的各种“坏味道”:

1.类名,方法名,变量名不易理解

随着工作时间的增长,我越来越觉得一个好的名称是多么的重要。一个好名称最重要的衡量标准就是易于理解,一看名称就知道这个类,方法大概的功能是什么,变量代表的是什么,可以给代码的阅读与理解写带来极大便利。对于名称,尽量取得准确,有意义,易于理解,如果不知道用什么单词,可以用词典查一下,请不要吝啬这取名字的时间。类名和变量一般是名词,而方法名一般是动词开头,宁愿名称长一些而准确也不要随意缩写,因为那个名字很有可能只有当时的作者才认识。

2、类,方法中包含过多代码

当一个类中有几千行,一个方法有几百行代码,你还看得下去吗?估计又想骂人了。这种情况绝大部分都是不正常的象征,除非特例。造成这种现象最主要的原因就是面向对象设计思想不过关,依旧停留在面向过程当中,导致类和方法包含了过多行为。带来的后果是代码可读性差,复用率低,扩展困难,这种代码的可维护性几乎是零。改进方法是按照面向对象的思想,将类中的行为分散到不同的类中,尽可能做到一个类担负专有职责,多个类共同协作完成同等工作;对于方法,应该根据功能点抽取成多个方法,提高代码复用率。

3、缺少必要空格

有些人写的代码几乎就没有空格,显得非常拥挤,不利于阅读。应该在变量与等于号之间、变量名称与逗号之间等加上空格;虽然这是个很小的细节,但是有句话说得好:勿以恶小而为之。

4、dao、controller包含过多业务逻辑

大家如果是做web开发的话,肯定都是分层开发的。各个层的职则划分我想大家也很清楚,但我却看到有些人把业务逻辑都写到dao,controller中,严重与各层职则相悖。正确的做法应该是将业务逻辑放在service层,即使是service层也要根据业务需求,适当的将职责划分到不同的方法或类中,切不可将代码千篇一律的堆在一个方法中。

5、if语句太多

大家肯定看过在一个方法中有很多个连续的if else语句,如果说每个判断中的逻辑非常简单,比如工厂类中根据某数据生产不同的对象,仅此而已,这种情况是正常的。可怕的是每个判断中都有一大串代码,造成这种情况的原因一般都是不同场景下有着不同的逻辑,却没有对这些逻辑抽象和封装,最后以过程式代码书写在一个方法中。这也会直接造成方法代码过长,复用率低,扩展性差。像这种情况基本上都可以通过策略模式或状态模式来抽象这些场景,将这些不同场景相关逻辑封装到策略或状态对象中,这样既可以提高扩展性,又可以简化客户端调用。

6、标记变量滥用

标记变量是指某变量取不同值时有着不同业务逻辑。比如,有个 type字段,值为1时代表谋类型,值为2时代表另外一种类型,以此类推…。写代码时应该尽量避免这种情况,因为标记变量各种取值的意义只有你自己知晓,对别人来说很难理解,特别是不同取值取连一个有意义的名称都没有。而且标记变量很容易造成if else语句过多的情况。
解决办法是:
第一种:把不同取值定义成常量,并取一个有意义的名字,最好让别人一看就知道这个值代表的意义是什么;对这些取值进行if判断时,
将判断条件抽取成一个boolean值方法,并为这个方法取一个有意义的名字,使代码更易理解,这里也再次说明取一个好名称的重要作用。
第二种:将不同取值转化成枚举,因为这种情况下不同取值的数量是有限的,确定的,很符合枚举的使用场景。
更为重要的是枚举中还可以定义方法,这样就可以将一些与特定取值的逻辑封装在不同的枚举元素中,这是常量所做不到的。
第三种:根据标记变量的不同取值封装到不同的策略或状态对象中,这样扩展性好,当多出一个新的取值时,只需要新增一个策略或状态类即可。

7、缺少必要注释

我觉得大部分开发人员写注释还是比较少的,一是没有养成写注释的习惯;二是嫌麻烦,觉得注释没什么用;还有就是时间因素,毕竟项目中时间是有限的。我的观点是:如果时间允许,尽量都写注释,特别是业务逻辑比较复杂的方法。有人可能会说,不用写也可以,代码是我自己写的,我都看得懂,能理解。当时是能理解,但是十天半个月之后就未必了,况且代码不仅是给自己看得,同时也是给别人看的。一个方法,别人看注释十秒钟就看懂了,没有注释可能要花十分钟,这就是注释的作用。一般人都不是软件大师,写的代码并不是都那么优秀,而注释能在一定程度上弥补我们代码的不足。而且大师写出来的代码都有注释,何况我们呢。

8、类中包含测试main方法

造成类中有测试main方法的原因是没有写单元测试,而经常又有测试的需要,为了图一时方便直接将测试代码写在了类中,测试完了后又没有删除main方法。应该将测试放至单元测试中,条件允许的话尽可能多写单元测试,这样可以排除掉很多潜在异常。

9、方法中包含过多的参数

如果一个方法参数太多会给客户端调用带来困难,客户端最喜欢的方法是一个参数都没有。不过所有方法都没有参数这是不可能的,但我们可以把方法参数个数尽可能减少。比如写多个重载方法,给一些参数赋默认值,以减少参数个数,重载方法最终都调用全参数方法。再如将多个参数封装成一个参数对象。个人认为,当方法参数超过三个就应该动动“手术”了。

10、包含e.printTrace语句

这条语句经常看见,如果程序是在本地运行,异常是有输出的。但是程序发布后运行在服务器上时就不会有任何输出。这条语句出现的原因,要么是开发是贪方便,要么是不知道使用log4j或其他日志记录工具记录日志(概率不大)。这会造成程序运行在服务器上缺少日志问题,而很多时候日志是排查问题的首选依据,所以,请将该语句换成logger.xxx

11、包含过多字面常量

现象:程序中存在很多字面常量(局部变量),比如:1、2、3…,字符串常量等
危害:给常量值修改带来很大麻烦,寻找散落在程序各个角落是一件费时费力的体力劳动,还要担心某些常量还未被更改;而常量值修改是再正常不过的事。
解决方法:将字面常量定义为public static final类常量,引用常量时直接引用这些静态类常量。

12、使用了sun子孙包中的类

现象:使用了jdk中sun子孙包的类,如:BASE64Encoder
危害:jdk中,java子孙包中的类是公开发布的,高版本jdk api必须兼容低版本jdk api,这是jdk对广大java开发者的重要承诺。而sun子孙包中的类不保证兼容性,因为它们是jdk开发组使用的,一般比较底层。如果你使用了sun子孙包中的类:
a.编译时会出现警告
b.升级jdk后可能编译无法通过,需要修改代码
解决方法:不使用sun子孙包中的类,自己实现或采用第三方类库

13、语句块大括号问题

现象:for,if语句块中只有一条语句时,省略了大括号
危害:影响代码书写一致性,如果代码块新增一条语句,依旧需要添加大括号
解决方法:每个语句块都添加大括号,即使语句块中只有一条语句。省略大括号可能是受C语言的影响,java中则一般不省略。
说到这呢,Java大括号位置也是如此,Java的打括号是左半边位于右上方,右半边位于左下方,而C语言则都位于左侧。
当然并不是说java风格的大括号就要比C风格的好,但你选择了某语言就应当遵守该语言的相关惯例与规范。

14、过多的字符串相加

现象:代码中过多的字符串直接相加
危害:本来字符串相加是再正常不过的事情,但是,当用于相加的字符串数量很大时,就不应该直接用加号相加。
由于String是常量,用加号相加时会不断产生新对象,特别是字符串数量很多的情况,浪费内存,性能也不好,而且不利于修改。
解决方法:
a.使用String.format,这适用于字符串数量不是很多的情况,数量很多,特别是数量还不确定的情况则使用方法b
b.使用StringBuilder或StringBuffer对象进行字符串相加。 StringBuilder是线程不安全的, StringBuffer是线程安全的,
但是很多人在方法内部进行字符串相加时用的却是 StringBuffer,在方法内部是不会出现多线程情况的,所以使用 StringBuilder即可。

15、保留了冗余逗号(Javascript)

现象:在JSON数组中,各个元素以逗号分隔,因格式书写原因,很多人在最后一个元素后保留了逗号。
危害:大部分浏览器兼容了这种情况,并不会出错,但也有例外(IE)。
解决方法:为了严谨起见,请把冗余的逗号去掉。

16、数据库表名,字段名称不规范

这里且不论数据库表的设计是否符合业务需要,只论表名与字段名。
现象:同一数据库中的表与表字段名称有大写的,小写的,大小写混合的,驼峰式的,下划线连接的,简直乱成了一锅粥。
危害:名称不规范,不利于阅读与理解,与很多开发人员的命名方式相违悖。
解决方法:表名与字段名一般都为大写,各个单词之间使用下划线("_")相连,表名与字段名都有注释。

    综上所述,本人深感开发一个好的软件的不容易,不利因素太多了:人力、开发成本、时间、开发人员水来。作为一个开发人员,很多因互是我们所决定不了的,但是自身的水平却是是自己可以把握的。一个开发人员应该在开发的过程有所收获,努力提高自己的开发水平,写代码的习惯与态度是前提,如果这一点都做不到,我想水平一般也不会高到哪去。所以请注意自己写代码的水平与态度!

    本人极力推荐看一本书:《重构_改善既有代码的设计》,相信看完之后一定会有所收获(大神除外)。

请注意写代码的习惯与态度(Java)的更多相关文章

  1. Web前端开发最佳实践(10):JavaScript代码不好读,不好维护?你需要改变写代码的习惯

    前言 这篇文章本应该在上一篇文章:使用更严格的JavaScript编码方式,提高代码质量之前发布,但当时觉得这篇文章太过基础,也就作罢.后来咨询了一些初级的开发者,他们觉得有必要把这篇文章也放上来.尽 ...

  2. 请手写代码实现一个promise

    第一步:promise的声明 class Promise{ // 构造器 constructor(executor){ // 成功 let resolve = () => { }; // 失败 ...

  3. jQuery 之父:每天写代码

    去年秋天我的支线代码项目 遇到了一些问题,项目进展不足,而且我没法找到一个完成更多代码的方法(在不影响我在Khan Academy方面的工作的前提下). 我主要在周末进行我的支线,当然有时候也在晚上进 ...

  4. jQuery之父:坚持每天都要写代码

    关于作者:John Resig, jQuery之父,同时也是Pro Javascript Techniques和Secrets of the JavaScript Ninja的作者.他目前主持 Kha ...

  5. 写代码有这16个好习惯,可以减少80%非业务的bug

    前言 每一个好习惯都是一笔财富,本文整理了写代码的16个好习惯,每个都很经典,养成这些习惯,可以规避多数非业务的bug!希望对大家有帮助哈,谢谢阅读,加油哦~ github地址,感谢每颗star ❝ ...

  6. [No000008]发工资不仅仅是让你写代码的

    这是我对团队每个新进员工说的第一件事情.这句话的意思是,我并不关心你是如何快速完成任务的,哪怕代码很差,只要它像救生艇通气门一样管用就行.这句话也是我最喜欢的座右铭之一. 这个说法其实很合理:我们的工 ...

  7. 写代码怎能不会这些Linux命令?

    转自:https://zhuanlan.zhihu.com/p/28674639?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=to ...

  8. 浏览器上写代码,4核8G微软服务器免费用,Codespaces真香

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 一图胜千言 先上图,下面是欣宸在自己的iPad Pro ...

  9. 使用 .NET WinForm 开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

    直接切入正题,这是我09年到11年左右业余时间编写的项目,最初的想法很简单,做一个能拖拖拽拽就直接生成应用程序的工具,不用写代码,把能想到的业务操作全部封装起来,通过配置的方式把这些业务操作组织起来运 ...

随机推荐

  1. WebLogic域配置策略

    WebLogic域配置策略--手动和模板选项,第一部分 域含有BEA WebLogic Server实例的配置信息.它包含有关服务器.集群和机器的配置信息.域还含有关于资源,例如Java数据库连接(J ...

  2. jsonp学习

    使用 JSONP 实现跨域通信:http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/

  3. jsoup 使用总结1--添加header

    jsoup 使用总结1--添加header 大部分时候,我们使用jsoup解析网页的是否都是直接Jsoup.connect(url); 孰不知,我们可以添加header,例如 Host, Refere ...

  4. Bootstrap 4,“未捕获错误:Bootstrap工具提示需要Tether(http://github.hubspot.com/tether/)”

    如果出现了这个错误,我想你是没有引用tether文件,这在v4之前不需要单独引入的. https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/te ...

  5. 微软黑科技强力注入,.NET C#全面支持人工智能

    微软黑科技强力注入,.NET C#全面支持人工智能,AI编程领域开始C#.Py--百花齐放 就像武侠小说中,一个普通人突然得到绝世高手的几十年内力注入,招式还没学,一身内力有点方 Introducin ...

  6. 蚂蚁 RPC 框架 SOFA-RPC 初体验

    前言 最近蚂蚁金服开源了分布式框架 SOFA,楼主写了一个 demo,体验了一下 SOFA 的功能,SOFA 完全兼容 SpringBoot(当然 Dubbo 也是可以兼容的). 项目地址:Alipa ...

  7. mina框架tcpt通讯接收数据断包粘包处理

    用mina做基于tcp,udp有通讯有段时间了,一直对编码解码不是很熟悉,这次做项目的时候碰到了断包情况,贴一下解决过程, 我接受数据格式如下图所示: unit32为c++中数据类型,代表4个字节,由 ...

  8. python 面向对象终极进阶之开发流程

    好了,你现在会了面向对象的各种语法了,  但是你会发现很多同学都是学会了面向对象的语法,却依然写不出面向对象的程序,原因是什么呢?原因就是因为你还没掌握一门面向对象设计利器, 此刻有经验的人可能会想到 ...

  9. .NET开发微信小程序-Template模块开发

    1.添加一个文件目录,里面放模板信息 例:我在根目录添加一个文件夹:template 然后在这个文件夹下面添加相应的页面.比如我添加一个promodel.wxml文件.主要是放商品相关的模块信息(注: ...

  10. vue实现双向数据绑定的原理

    vue实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的. 在MDN上对该方法的说明是:O ...