有关重构项目的一些小经验

最近开始重构,发现重构真的是即恶心又爽的一件事。不断的发现问题,解决问题。

个人觉得后端重构要注意以下的几个点:

最重要的一点:新启一套接口和方法去重构,同时保证两套系统的可用性。

  • 1.定义和前端协议参数的时候,名称,参数类型一定要统一,并列成一个表格放在公司wiki上。

(1)类似我们原有代码,对于定义定向id,有的叫targetingId,有的叫mid。可理解性差。不同get接口应该传的是一个同一个值,却命名不一致。

(2)还有的用户id,都是advertiserId,有的是Long类型,有的是String类型,后端service统一接收的是Long,在controller层又通过这种无效代码转换成Long。

Long aid =Long.parseLong(advertiserId);
  • 2.将所有特殊逻辑文档化,流程图化。

首先我们的广告系统业务逻辑及其复杂。重构除了把代码优化外,文档化也是很重要的。

很多系统没有有关特殊逻辑的梳理,导致后面排查外网问题,需求评审时候要重新梳理一遍逻辑。

还有可能修改一个点不小心影响到其他点,然后导致踩坑。

本次使用了swagger文档工具。还是蛮好玩的。

  • 3.service层将实现功能细维度,可复用组装性高一点。

作为复杂逻辑的应用层系统,会调用多方的接口。

在service层级,要尽量保证一个方法只实现一个功能,不要把一堆功能组装在一起,一个方法调用了5,6个其他服务方的接口,很难定位问题。

  • 4.重构过程中补齐单元测试

单元测试补齐也是很重要的一点。

基于serviceImpl层级,要保证每一个方法的单元测试补齐。

一方面实现在开发过程中实现“测试驱动开发”,先写单元测试,再开发代码。

提交代码到SVN和Git之前,先跑单元测试,单测跑成功之后才可以提交代码。

  • 5.使用业界的阿里编码规约扫描项目

扫描发现有三个层级的问题:

(1)Blocker(崩溃):

1》在使用正则表达式时,利用好其他、预编译功能,可以有效加快正则匹配速度:

原始代码类似如下:

 public static String replaceBlank(String str) {
    String dest = "";
    if (str!=null) {
      Pattern p = Pattern.compile("|\t");
      Matcher m = p.matcher(str);
      dest = m.replaceAll("");
    }
    return dest;
  }

修改成:

 private final static Pattern pattern = Pattern.compile("\t");

 public static String replaceBlank(String str) {
    String dest = "";
    if (str!=null) {
      dest = pattern.matcher(str).replaceAll("");
    }
    return dest;
  }

2》if...else...没有加大括号,没必要举具体的demo,标准的格式应该是这样的。

 if (条件) {
  //do something
 } 
 else {
  //do something
 }

3》 所有包装类对象之间值的比较,全部使用equals方法比较:

之前代码中有的uid这种使用了Long,然后使用了==去比较,这样是不合理的,将==改成了equals。

4》所有的覆写方法,必须加@Override注解:

这个比较好理解,类似于有的aaaServiceImpl类实现了aaaService接口,但是在Impl中实现接口的部分方法没有加@Override注解,补充一下就ok了。

5》避免通过一个类的对象饮用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接使用类名来访问即可。

静态方法可以直接使用类名访问。具体可以见我的博客:《Static和final关键字解析》

(2)Critical(严重):

1》常量命名应该全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。

类似于USER_NAME一定要大写。

private static final String USER_NAME = "userName";

2》不能使用过时的类或方法。

类似于我们的一个方法reject已经不用了,改用withError。修改掉就不会有这种错误了。

3》Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。

正确用法应该是

“aaa”.equals(userName)

而不是:

(userName).equals("aaa");

(3)Major(重要)

1》中括号是数组类型的一部分,数组定义如下:String[] args

我们代码里定义了一个数组:Field ff[]=XXXX;

应该变为  Field[] ff = XXX;

2》及时清理不再使用的代码段或配置信息。

说明:对于垃圾代码或过时配置,坚决清理干净,避免程序过度臃肿,代码冗余。

一般系统在经过测试,后续增加业务需求,很多人接手之后,会出现很多垃圾代码,有些代码被注释掉了,想着以后在用。

把这部分代码趁着重构,整体删除掉。

3》不允许任何魔法值(即未经定义的常量)直接出现在代码中。

有些判断里面可能直接判断if(("test").equals(a)){}

应该做法是

private static final String AAA = "test";

if(AAA.equals("a")){}

4》集合初始化时,指定集合初始值大小。

说明:HashMap使用如下构造方法进行初始化,如果暂时无法确定集合大小,那么指定默认值(16)即可。

5》所有的类都必须添加创建者信息.

6》事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务。

7》类、类属性、类方法的注释必须使用javadoc规范,使用/**内容*/格式,不得使用//xxx方式和/*xxx*/方式。 说明:在IDE编辑窗口中,javadoc方式会提示相关注释,生成javadoc可以正确输出相应注释;在IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。

8》所有的抽象方法(包括接口中的方法)必须要用javadoc注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。

你可能感兴趣的:(java)