技术记录栈

记录点滴:java、datebase、linux、spring、javascript、nginx

2019/01/20

如何编写高质量代码

编写代码并不难,编写高质量的代码却很难。请记住,编写和重构高质量代码,从而使应用程序更加健壮,什么时候开始都不会太晚。

在各种框架流行的时代,我们需要编写的代码量大幅缩减。很多时候,开发人员在压力下编写复杂的代码,代码质量一般都会缩水。就高质量代码而言,一个好的经验法则是,任何人都可以像读短语一样阅读你所编写的代码,代码可读性很大程序上决定了代码的质量。在这个硬件日新月异,分布式大行其道的年代,一切以牺牲代码可读性的编码,都是拙劣的写法。所以,有必要回顾一下高质量代码的一些基本要求。

编写代码时的注意事项

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

遵循最佳实践。

使用代码质量管理工具,如: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行代码。

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

如果,在单独的方法中处理发送邮件,每个方法都可以使用该代码,这样,在每个方法中只需要10行,而无需一次又一次地编写发送逻辑。