如何编写高质量代码

编写代码并不难,编写高质量的代码却不易。为了让应用程序更加健壮,现在就开始编写/重构高质量代码也不算太晚。

在这个框架泛滥的时代,完成一个项目需要编写的代码量大幅缩减。很多时候,我们对框架的重视程度已超过了代码质量,再加上过度追求项目进度的管理者,致使开发人员顶压力进行高强度的编码,代码质量通常都令人堪忧。高质量的代码不再是一种追求而是奢求,所以,有必要回顾一下高质量代码的一些基本要求。就高质量代码而言,一个好的经验法则是,任何人都可以像读文章一样阅读所编写的代码,代码可读性很大程序上决定了代码的质量。在这个硬件日新月异,分布式大行其道的年代,一切以牺牲可读性的编码,都是拙劣的写法。

编写代码时的注意事项

思考在前,动手在后,写一次想两次。

遵循最佳实践。

使用代码质量管理工具,如:Sonar插件(SonarLint),一般都支持常见的IDE。

尝试编写通用代码。

为自己的程序命名时,不要与众所周知的API起冲突,如:isEmpty,isNull或isNotNull。

IDE的快捷重构功能是应该掌握的基本技能。

在大面积替换时,尽量使用IDE的Refactor Tool,防止遗漏与错误修改。在做代码分解时(如:把1-4行中的代码提取出来创建一个单独的方法),通常的做法是创建一个方法,然后复制所需行并粘贴到该方法中,这需要3或4个步骤。执行此类任务,可以使用IDE的快捷重构(Refactor Tool)功能,而不是复制和粘贴。重构工具有许多重要功能,需要一一摸索。

类命名注意事项

类名应该是名词,每个单词的首字母应该大写。

在编写新类之前要进行全局搜索,项目中可能已存在这样的文件。很多时候,我们会使用不同的名称创建相同的功能,从而对项目中其他开发人员产生误导。

已存在                 新创建

AppUtil               ApplicationUtil

ConfigutationUtil     ConfigurationHelper

LoggerUtil            LoggerHelper

类名应该足够清楚准确的描述它的核心功能

不提倡                    提倡

PersonRestApi             PersonController

PersonRest                PersonController

PersonImplementation      PersonService

使用适当的访问修饰符。

package的命名也非常重要,把正确的文件放在正确的地方,不要把常量文件放在util包中。

方法编写注意事项

方法名是动词,应遵循驼峰原则,比如:doWhatToDo(),而不是doWHatTODO()。

一个方法的长度不应超过30行,相反,就是在增加方法的复杂性。

在定义方法之前,要考虑它应具有某种意义,或者是为特定任务所创建,例如createPerson或sendMail。

方法不应同时包含多个任务。如果方法的名字是:createPerson,那么,它就应该只用于创建Person,别无其他。通常,会见到如下的万金油写法:

public Long createPerson(PersonVO personVO) { 
    1.Appointment appointment = trying to getting an appointment from DB.
    2.then performing if else over the result of appointment.
    .
    .
    .
    .
    14.then updating something on the basis of some condition.
    15.then finally creating person.
 }

很多时候,开发人员在一个方法中放入100-300行代码,它已超越了方法的极限,最后,使代码变得可怕和难以理解。

很多时候,开发者会觉得这是在优化代码的调用效率,其实,完全没必要,这种调用优化是HotSpot VM的强项。

尝试在单独的方法中组合多个方法。

public  Long  createPerson(PersonVO  personVO){
  appoitnmentValidation();
  updatesSomething();
  creating person code;
 }

变量命名注意事项

变量名称应遵循驼峰原则:isTrue,userService,personName和localServiceRerpository。
除个别情况外,不应使用一个字符作为名称。
不应该以_和$开头。
在定义变量名称之前先想一想。
不要把变量名称命名太长。

常量命名注意事项

尝试使用类来定义常量,而不是接口。

将Class标记为final。

在常量类中创建一个私有的构造函数,防止对其创建实例。

如果有一个常量列表,那么,通过以下方式的注释,对常量进行隔离是个好主意。它会使搜索更容易。

/**** Cache ****/
public static final String CACHE_NAME = "personCache";
/**** Attributes ****/
public static final String NAME = "name";
public static final String MOBILE = "mobile";
/**** Configuration ****/
public static final String APP_NAME = "PersonDemo";
public static final String APP_VERSION = "1.0";

常量命名应该是非常具体的,并且,应该全部是大写的,并且用下划线(_)分隔,比如APP_NAME,而不是appName。

编写代码逻辑注意事项

避免if else多层嵌套,会增加代码的复杂度。

尝试编写通用代码。

不要只使用日志打印异常,应适当的抛出异常消息,或直接把异常来打印出来。

什么是“通用代码”

在项目重构时,应被剔除的冗余代码。

假设,有一个表示邮件的POJO类,与发送邮件相关的类。那些发送邮件需要遵循的步骤是什么呢?

1、创建一个POJO对象,通过使用setter来选择要发送的数据。

2、编写发送邮件的代码。

如下所示:

创建对象:

MailDraft mailDraft = new MailDraft();

设置数据:

mailDraft.setTo(); 
mailDraft.setBody(); 
mailDraft.setMessage();

发送邮件逻辑最少有4行,所以共有9-10行代码。

如果,需要在多个地方发送邮件会怎样?需要相同的逻辑。通常,开发人员只是在各个地方重复相同的步骤,创建一些具有某些特定代码的方法,导致代码产生冗余。

如果,在单独的方法中编写邮件发送逻辑,每个邮件业务都调用该代码,这样,在邮件业务代码中只需简单的几行代码,而无需一次又一次地重写发送逻辑。