17 设计原则 :快速改善代码质量的周末

129 阅读4分钟

这一节的学习跟代码整洁之道更像,更多的是说一些代码实现规范,可以直接作为coding准则,今天记住明天用的规范,更为具体。

1.命名

命名这件事很重要,但是一些方法名字,类名,确实不是那么好起名字。

  • 代码整洁之道说的是宁长毋滥,实在是过长的话,才可以考虑简写
  • 利用上下文简化命名
//错误代码
public class User {
private String userName;
private String userPassword;
private String userAvatarUrl;
//...
}
//正确实例
public class User {
private String Name;
private String Password;
private String AvatarUrl;
//...
}
  • 命名要可读、可搜索

我们在 IDE 中编写代码的时候,经常会用“关键词联想”的方法来自动补全和搜索。比如,键入某个对象“.get”,希望 IDE 返回这个对象的所有 get开头的方法。再比如,通过在 IDE 搜索框中输入“Array”,搜索 JDK 中数组相关的类。 所以,我们在命名的时候,最好能符合整个项目的命名习惯。大家都用“selectXXX”表示查询,你就不要用“queryXXX”;大家都用“insertXXX”表示插入一条数据,你就要不用“addXXX”,统一规约是很重要的,能减少很多不必要的麻烦。

- 如何命名接口和抽象类?

一种是加前缀“I”,表示一个 Interface。比如 IUserService,对应的实现类命名为 UserService。 另一种是不加前缀,比如UserService,对应的实现类加后缀“Impl”,比如 UserServiceImpl。

2.注释

注释的目的计算让代码更容易看懂。注释起到总结性作用、文档的作用

我见过Google原生代码,对每个类都有一个概述性的注释,这样最起码让我知道这个类的作用。相比于此,我们普通的项目,每一个类都是没有注释,特别是对于刚刚加入项目的成员来说,真的是晦涩难懂。

注释是不是越多越好?

注释太多和太少都有问题。太多,有可能意味着代码写得不够可读,需要写很多注释来补充。除此之外,注释太多也会对代码本身的阅读起到干扰。而且,后期的维护成本也比较高,有时候代码改了,注释忘了同步修改,就会让代码阅读者更加迷惑。当然,如果代码中 一行注释都没有,那只能说明这个程序员很懒,我们要适当督促一下,让他注意添加一些必要的注释。

3.类、函数的大小

类或函数的代码行数太多,一个类上千行,一个函数几百行,逻辑过于繁杂,阅读代码的时候,很容易就会看了后面忘了 前面。相反,类或函数的代码行数太少,在代码总量相同的情况下,被分割成的类和函数就会相应增多,调用关系就会变得更复杂,阅读某个代码逻辑的时候,需要频繁地在 n 多类或者 n 多函数之间跳来跳去,阅读体验也不好。

  • 一个函数不要超过一个屏幕,一个屏幕之后需要来回切屏,影响理解。
  • 如果你要在类里找个函数,需要找半天,那说明类也过大。
  • 对于一行代码,尽量也不要超出屏幕,如果屏幕很大,,假如你搞了一个32寸的显示器搁哪里写代码,那就不要超过100字符了。
  • 并不是只有函数之间用空格划分,函数内不同的语句块,也可以用空行分割。
pulbic void initView(){
    initData();
    catchData();
    
    intiView();
    setViewClickListener();
}
  • 成员变量之间或函数之间,都是按照“先静态(静态函数或静态成员变量)、后普通(非静态函数或非静态成员变量)”的方式来排列的。
  • 成员变量之间或函数之间,还会按照作用域范围从大到小的顺序来排列,先写 public成员变量或函数,然后是 protected 的,最后是 private 的。

4.适度封装

  • 把代码分割成更小的单元块
// 重构前的代码
public void invest(long userId, long financialProductId) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.DATE, (calendar.get(Calendar.DATE) + 1));
    if (calendar.get(Calendar.DAY_OF_MONTH) == 1) {
        return;
    }
//...
}

// 重构后的代码:提炼函数之后逻辑更加清晰
public void invest(long userId, long financialProductId) {
    if (isLastDayOfMonth(new Date())) {
        return;
    }
//...
}
public boolean isLastDayOfMonth(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.DATE, (calendar.get(Calendar.DATE) + 1));
    
    if (calendar.get(Calendar.DAY_OF_MONTH) == 1) {
        return true;
    }
    return false;
}

5.参数封装

  • 函数参数超过3个就应该立马封装成一个对象。
  • 不要用参数控制逻辑代码

6.函数单一职责

对于函数的设计来说,更要满足单一职责原则。相对于类和模块,函数的粒度比较小,代码行数少,所以在应用单一职责原则的时候,没有像应用到类或者模块那样模棱两可,能多单一就多单一。

7.移除过深的嵌套层次

代码中的准则是尽量只用一层if-else,for循环,如果使用过多,代码的看着难以阅读。 建议使用if-retrun的方式

8.学会使用解释性变量

public double CalculateCircularArea(double radius) {
    return (3.1415) * radius * radius;
}

// 常量替代魔法数字
public static final Double PI = 3.1415;

public double CalculateCircularArea(double radius) {
    return PI * radius * radius;
}