代码整洁之道学习总结 - 菜鸟程序员初入门,让代码质量成为自己的名片

命名

命名规则

  1. 表明变量/方法的用途
  2. 不是List类型的变量不要用xxxList结尾,应该用xxxs命名:比如一组账号不要用accountList,应该用accounts
  3. 不要做没有意义的命名:比如moneyAmount与money没有区别,customerInfo和customer也没有区别,accountData与account没有区别
  4. 命名要能够读得出来(英文单词的组合)
  5. 可搜索的名称(名称长短应该对该变量作用域的大小)
  6. 类名命名规范:应该是名词或者名词短语,如Customer、Wikipage、AddressParser等,类名不应该是动词。
  7. 方法名应该是动词或者动词短语,对属性(成员变量)的访问用getXXX,修改用setXXX,判断用isXXXX。
  8. 对同一种概念应该用相同的名词后缀(不要使用近义词英文),比如控制器统一用xxxController不要一些用xxxController,一些用
  9. 给一组变量添加有意义的语境(比如把这些变量都放到一个类里面给读者提供语境,如果不能就加上前缀或者后缀)

函数

  1. 短:函数的缩进不应该多于一层或两层,if 、else、while语句中的代码应该只有一行
  2. 函数只做一件事:函数中的语句要在同一抽象层级上,这个函数应该引出下一个抽象层的函数。函数的功能可以解释为:要做xxxxx(),然后做xxx(),最后做xxx() 。这三个函数就是下一抽象层要做的东西
  3. switch语句中应该下沉到较低的抽象层,switch的每个分支中用工厂方法创造出不同的接口实例,然后上层函数对接口编程
  4. 长而明确的函数名比短而模糊的
  5. 函数入参(无 -> 一个参数 ->两个参数 -> 三个参数):
    5.1 一元参数:①问关于该参数的问题boolean fileExists(“MyFile”) ②操作该参数,转换为其他东西 InputStream fileOpen(“MyFile”) ③事件,void passwordAttempFailedNtimes(int attempts) ,改变状态
    尽量不要写不符合这三种情况的函数,比如用输出参数而不用返回值,如 StringBuffer transform(StringBuffer in) 好于 void transform(StringBuffer out) , 不要使用布尔值作为入参
    5.2 超过三个参数以上考虑把其中某几个参数封装为一个类中的字段
    5.3 避免使用输出参数 : 输出参数就是会被一个变量的应用被当作入参传入函数,然后在函数中改变了该引用所指向的对象。如report.appendFooter() 比appendFooter(report)要好
  6. 函数要不就是做什么,要不就是回答什么事,不能两件事同时做,所以尽量不要写做什么成功后返回true,失败后返回false的函数
  7. 使用异常代替错误码,同时,用throw 代替try catch , catch只在最外层抓住。
  8. 函数的编写方法,初稿可以先是能实现功能的混乱代码,写完后配上一套单元测试,然后再重构

注释

原则:能不写注释尽量别写

好的注释

  1. 提供函数基本信息,提供代码意图,解释一些难懂的函数返回结果,警示,TODO,放大某种不合理事物的重要性

格式

垂直距离

  1. 包名、引入、每个函数之间空一行
  2. 变量要靠近使用它的位置、函数本地变量要出现在顶部
  3. 被调用函数要在被调用函数下面

水平距离

  1. 赋值语句,加减运算符左右空格

格式规范例子

  1. 变量位于类顶部
  2. 构造函数位于变量之后
  3. 算术表达式前后有空格,布尔表达式前后有空格,函数声明 “{” 前有空格,for if while 后有空格,“:” 前后有空格

数据、对象的反对称性

  1. getter和setter的目的是为了把对对象数据的访问抽象化
  2. 数据结构与对象的区别:①数据结构暴露数据,没有提供有意义的函数;②对象封装函数,暴露操作数据的函数。这称为反对称性,数据结构便于增加方法,而对象便于增加类型。
  3. 得墨hao 定律:类C的方法 f 只应该调用以下对象的方法:①类C ②类C实例变量对象的方法 ③f 创建的对象 ④f 的参数对象

错误处理

  1. 使用异常而不是错误码
  2. 先写try catch finally语句
  3. 使用不可控异常:所谓不可控异常就是不被声明的,可控异常就是使用已知的异常,这样在底层网上抛的时候每一层都要捕获或者抛出这个异常
  4. 对于调用第三方的API,可以把其抛出的异常打包一个异常类
  5. 不要返回null值,用返回特例对象或者抛出异常代替
    特例对象就是把下层调用中可能会出现Null的情况在下层调用做一个封装,或者把对第三方调用做一层封装,出现Null时创建特例对象,然后返回给上层
  6. 不要传递Null值,入参不要传递null,应该用函数重构处理掉

边界处理

1、对于第三方API , 写学习性单元测试,就是写关于这个API使用方式的单元测试。
2、对于外部调用服务API,通过adapter的方式转换为自己想要的服务
比如对于类Map<k,V> , map.get(k) 往往需要强制类型转化如下代码:

Map sensors = new HashMap();
Sensor s = (Sensor) sensors.get(sensorId);

//或者一般在创建的时候就会指定类型
Map<String, Sensor> sensors = new HashMap<String, Sensor>();
Sensor s = sensors.get(sensorId)

更好的做法是定义一个方法把显示转换写到方法里面,如:

public class Sensors {
    private Map sensors = new HashMap();
    public Sensor getById(String id) {
    	return (Sensor) sensors.get(id);
    }
}

这样就不用每次调用这个map的get方法都要显示转换。

测试代码整洁性

1、每个测试方法应该只包含 数据构造 -> 调用方法 -> 判断(assert) 几步
2、每个测试方法只测试一个概念且断言(assert语句应该尽量少,最好只有一个)
3、测试代码的原则:first
F: fast - > 运行应该足够快
I: independent -> 测试应该独立的,相互之间没有时序依赖性
R: repeatable -> 在任何环境(线下 or 线上) 都是要可通过的
S: self-validating -> 测试一定要有断言assert判断对错,不通过日志确认是否通过测试
T: timely -> 及时的,测试在写其对应的生产代码前编写(实际操作有点难)

类的整洁性

  1. 单一权责原则(SRP) :一个类只有一个修改它的理由
  2. 类的内聚性不能太高:一个类中如果每个方法都会引用到一个类的所有成员变量,那这个类的内聚性是最高的。
  3. 当类丧失内聚性时就该把它拆分为更多的短小的类(让类的实例变量和调用这些变量的方法抽象到另一个类中)
  4. 开放-闭合原则(OCP):一个类应该对扩展开放(可被继承产生子类),对修改封闭
  5. 依赖倒置原则(DIP) :类应该依赖抽象(接口、抽象类) 而不应该依赖具体实现。

系统的整洁性

  1. 构造与使用分离:对象的初始化应该放在main()或者容器中,用工厂模式给应用自行确定创建时间。经典例子:Spring的依赖注入

迭进

四种原则去设计良好的软件:

  1. 运行所有的测试
  2. 不可重复:通过抽象方法或抽象基类的方法
  3. 表达力:命名;短小的类等
  4. 尽量减少类和函数的数量

并发

  1. 并发防御原则:
    ①单一权责原则(SRP) :尽量分离并发相关代码与其它代码
    ②限制数据作用域:用synchronized关键字限制作用域,这个作用域应该尽量小
    ③使用数据副本
    ④线程尽量独立:类的实体变量以函数参数的形式传递
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值