九折技术 九折技术
首页
  • Go
  • MIT-6824
  • 算法与数据结构
  • 面向对象
  • 代码整洁
  • 重构
  • 设计模式
  • 学习
  • 技术
  • 人文
关于
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub

HoldDie

长期有耐心,一切才刚刚开始!
首页
  • Go
  • MIT-6824
  • 算法与数据结构
  • 面向对象
  • 代码整洁
  • 重构
  • 设计模式
  • 学习
  • 技术
  • 人文
关于
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub
  • 代码整洁

    • 命名和注释
    • 代码风格
    • 编程技巧
    • 代码质量
      • 如何发现代码质量问题?
        • 常规 checklist
        • 业务需求
      • 程序出错返回啥?
        • 返回错误码
        • 返回 Null 值
        • 返回空对象
        • 真实案例
  • 重构

  • 设计模式

  • 架构
  • 代码整洁
holddie
2020-08-24

代码质量

# 如何发现代码质量问题?

# 常规 checklist

  • 目录设置是否合理、模块划分是否清晰、代码结构是否满足“高内聚、松耦合”?
  • 是否遵循经典的设计原则和设计思想(SOLID、DRY、KISS、YAGNI、LOG)?
  • 设计模式是否应用得当?是否有过度设计?
  • 代码是否容易扩展?如果要添加新功能,是否容易实现?
  • 代码是否可以复用?是否可以服用已有的项目代码或类库?是否有重复造轮子?
  • 代码是否容易测试?单元测试是否全面覆盖了各种正常和异常的情况?
  • 代码是否易读?是否符合编码规范?

# 业务需求

  • 代码是否实现了预期的业务需求?
  • 逻辑是否正确?是否处理了各种异常情况?
  • 日志打印是否得当?是否方便 debug 排查问题?
  • 接口是否易用?是否支持幂等、事务等?
  • 代码是否存在并发问题?是否线程安全?
  • 性能是否有优化空间,比如 SQL、算法是否可以优化?
  • 是否有安全漏洞?比如输入输出校验是否全面?

# 程序出错返回啥?

# 返回错误码

  • C 语言没有异常这样的语法机制,返回错误码便是最常用的出错处理方式。
  • Java、Python 等比较新的编程语言,大部分情况下,我们都用异常来处理函数出错的情况,极少会用到错误码。

# 返回 Null 值

  • 在多数编程语言中,我们用 NULL 来表示“不存在”这种语义。
  • 对于查找函数来说,数据不存在并非一种异常情况,是一种正常行为,所以返回表示不存在语义的 NULL 值比返回异常更加合理。
  • 当然在 Java8 之后我们可以使用 Optional 进行空判断。

# 返回空对象

  • 返回 NULL 值有各种利弊,对此有一个比较经典的应对策略,那就是应用空对象设计模式。
  • 当函数返回的数据是字符串类型或者集合类型的时候,我们可以用空字符串或空集合替代 NULL 值,来表示不存在的情况,这样我们可以不用做 NULL 值判断。

# 抛出异常对象

  • 最常用的函数出错处理方式是抛出异常,异常有两种类型:受检异常和非受检异常。
  • 对于应该用受检异常还是非受检异常,我们需要根据团队的开发习惯,在同一个项目中,制定统一的异常处理规范即可。
  • 对于函数抛出的异常,我们有三种处理方法:
    • 直接吞掉
    • 直接往上抛出
    • 包裹成新的异常抛出
  • 对于是否向上抛出异常,要看上层代码是否关系这个异常。

# 真实案例


public class RandomIdGenerator implements IdGenerator {
  private static final Logger logger = LoggerFactory.getLogger(RandomIdGenerator.class);

  @Override
  public String generate() throws IdGenerationFailureException {
    String substrOfHostName = null;
    try {
      substrOfHostName = getLastFieldOfHostName();
    } catch (UnknownHostException e) {
      throw new IdGenerationFailureException("...", e);
    }
    long currentTimeMillis = System.currentTimeMillis();
    String randomString = generateRandomAlphameric(8);
    String id = String.format("%s-%d-%s",
                              substrOfHostName, currentTimeMillis, randomString);
    return id;
  }

  private String getLastFieldOfHostName() throws UnknownHostException{
    String substrOfHostName = null;
    String hostName = InetAddress.getLocalHost().getHostName();
    if (hostName == null || hostName.isEmpty()) {
      throw new UnknownHostException("...");
    }
    substrOfHostName = getLastSubstrSplittedByDot(hostName);
    return substrOfHostName;
  }

  @VisibleForTesting
  protected String getLastSubstrSplittedByDot(String hostName) {
    if (hostName == null || hostName.isEmpty()) {
      throw new IllegalArgumentException("...");
    }

    String[] tokens = hostName.split("\\.");
    String substrOfHostName = tokens[tokens.length - 1];
    return substrOfHostName;
  }

  @VisibleForTesting
  protected String generateRandomAlphameric(int length) {
    if (length <= 0) {
      throw new IllegalArgumentException("...");
    }

    char[] randomChars = new char[length];
    int count = 0;
    Random random = new Random();
    while (count < length) {
      int maxAscii = 'z';
      int randomAscii = random.nextInt(maxAscii);
      boolean isDigit= randomAscii >= '0' && randomAscii <= '9';
      boolean isUppercase= randomAscii >= 'A' && randomAscii <= 'Z';
      boolean isLowercase= randomAscii >= 'a' && randomAscii <= 'z';
      if (isDigit|| isUppercase || isLowercase) {
        randomChars[count] = (char) (randomAscii);
        ++count;
      }
    }
    return new String(randomChars);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
编辑
#代码质量
上次更新: 2020/08/24, 10:08:00
编程技巧
重构要点

← 编程技巧 重构要点→

最近更新
01
行为型-访问者模式
11-24
02
行为型-备忘录模式
11-24
03
行为型-命令模式
11-24
更多文章>
Theme by Vdoing | Copyright © 2019-2020 HoldDie | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式