注: 以下内容引自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. C# 添加、读取Word脚注尾注

    脚注和尾注是对文本的补充说明.脚注一般位于页面的底部,可以作为文档某处内容的注释:尾注一般位于文档的末尾,列出引文 的出处等.在本示例中将介绍如何来添加或删除Word脚注. 工具使用:Free Spi ...

  2. Object对象你真理解了吗?

    前言 五一回家又断更了一个放假时间了~~~ 只有光头才能变强 回顾前面: ThreadLocal就是这么简单 多线程三分钟就可以入个门了! 多线程基础必要知识点!看了学习多线程事半功倍 Java锁机制 ...

  3. JVM学习--(六)类加载器原理

    我们知道我们编写的java代码,会经过编译器编译成字节码文件(class文件),再把字节码文件装载到JVM中,映射到各个内存区域中,我们的程序就可以在内存中运行了.那么字节码文件是怎样装载到JVM中的 ...

  4. Maximum Subarray(最大子数组)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  5. dom4j 解析 xml标签属性

    重写onEnd()和onStart()方法 public class XmlElementHandler implements ElementHandler { @Override public vo ...

  6. 使用swagger管理接口

    swagger 配置 1.pom 增加jar包依赖 <dependency> <groupId>io.springfox</groupId> <artifac ...

  7. Hyper Text Transfer Protocol(超文本传输协议)

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...

  8. 【JDK1.8】JUC——AbstractQueuedSynchronizer

    一.前言 在上一篇中,我们对LockSupport进行了阅读,因为它是实现我们今天要分析的AbstractQueuedSynchronizer(简称AQS)的基础,重新用一下最开始的图: 可以看到,在 ...

  9. Spring消息之STOMP

    一.STOMP 简介 直接使用WebSocket(或SockJS)就很类似于使用TCP套接字来编写Web应用.因为没有高层级的线路协议(wire protocol),因此就需要我们定义应用之间所发送消 ...

  10. R贡献文件中文

    贡献文件 注意: 贡献文件的CRAN区域被冻结,不再被主动维护. 英文 --- 其他语言 手册,教程等由R用户提供.R核心团队对内容不承担任何责任,但我们非常感谢您的努力,并鼓励大家为此列表做出贡献! ...