注: 以下内容引自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. opencv基本图像操作

    // Basic_OpenCV_2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #i ...

  2. javascript语言扩展:可迭代对象(5)

    文章1-4篇说的都是js中的可迭代对象,下面让我们看看ruby中的等价物. 不可否认,ruby中对于迭代器和生成器的语法都相当简洁:ruby从一开始就有一个简洁的基因,而js后来的不断扩充使得其有些语 ...

  3. Java数据结构面试题,输出 最后一个 出现次数为1的字符

    今天去面试,遇到一个数据结构题,给定一个字符串,输出 最后一个 出现次数为1的字符 回来研究了下,代码如下: package com.pine.interview.test; import java. ...

  4. ubuntu18.04 安装mysql 5.7.22

    后台下载,脱离终端控制 后台下载,可以节省ssh资源占用,且不会因为ssh连接断开而导致下载失败,适用于操作远端云服务器 wget -b 启动后台下载 -o 指定logfile(记录下载进度信息) w ...

  5. java并发包分析之———Deque和LinkedBlockingDeque

    一.双向队列Deque   Queue除了前面介绍的实现外,还有一种双向的Queue实现Deque.这种队列允许在队列头和尾部进行入队出队操作,因此在功能上比Queue显然要更复杂.下图描述的是Deq ...

  6. Day19 Django

    老师代码博客: http://www.cnblogs.com/yuanchenqi/articles/7552333.html 上节内容回顾: class Book(models.Model): ti ...

  7. WSGI及gunicorn指北(二)

    pyg0已经大概了解了wsgi.现在他决定深入探索他们实际在生产环境里用到的web 服务器 -gunicorn. 先来看看官网的介绍:Gunicorn 是一个运行在Unix上的python WSGI ...

  8. 微软云消息队列 Azure service bus queue

    前言 第一次使用消息队列,遇到了一些问题:同一个消息有多次出列.是一个消息只入列一次,还是多次?还是因为出列问题,出列了多次? Microsoft Azure service bus queue Az ...

  9. htmlparser 学习

    htmlparser 学习系列 htmlparser 使用法使用与详解

  10. css 选择器【转】

    最近在研究jQuery的选择器,大家知道jQuery的选择器和css的选择器非常相似,所以整理一下css选择器: css1-css3提供非常丰富的选择器,但是由于某些选择器被各个浏览器支持的情况不一样 ...