代码整洁之道

来源:互联网 发布:动漫模型软件 编辑:程序博客网 时间:2024/05/21 18:36

不要想着稍后再改,稍后等于永不。

磨刀不误砍柴工,虽然重构代码会花费一些时间,但重构的代码会使你的系统的可扩展性更好

高内聚,低耦合。当代码需要改动时,不需要改动多处地方,只需要改动少部分,也不需要花费大量时间检查是否有错误

一、命名

命名须具有准确的描述,不要用含糊其辞的单词描述;

用名字代替常量,常量名称需大写

不需要前缀

类名是名词,方法名是动词

前后命名规则具有一致性

可使用专业名词

把具有相同语境的函数或类放在一起

不要怕名字长,但也不要为了长而长

二、函数

函数最重要的是“短小”、最好封顶为20行

函数的缩进层级不该多于一层或两层

一个函数只应该完成一件事,都在同一抽象层级上

用多态代替switch

使用具有描述性的名称

函数参数最好是零个,其次是一个,再次是两个,尽量避免三个

不要使用标识参数(true,false),不要使用输出参数

函数要么做什么事,要么回答什么事,两者不可兼得

使用异常替代返回错误码

最好把try/catch分离出来单独形成行数,错误处理就是一件事,在这后面不应有其他内容

不要重复自己,软件开发领域的所有创新都是在不断尝试从源代码中消灭重复

结构化编程:每个函数中只有一个return语句,循环中不能有break和continue

作者也不是一开始就写出这样的代码,而是经过重构之后得到这种代码的

三、注释

用代码名称代替注释

法律信息、提供返回信息,对意图的解释阐释某些晦涩难明的东西、警告、//TODO(待处理)、公共API中的Javadoc

不要写废话、不要为了注释而注释,不需要写日志,能用函数或变量表示时就不需要用注释,不要滥用标记,去掉注释掉的代码

四、格式

封包声明、导入声明、每个函数之间都应该用空白行分隔

紧密相关的代码应该互相靠近

本地变量应该在函数的顶部出现实体变量应该在类的顶部

一行代码最好不超过80个字符

赋值周围加上空格字符、函数名和空格之间不加空格,函数参数之间用逗号加空格,乘法不加空格,因为有较高的优先级,加减法加空格

不需要水平对齐

遵循团队规则

五、对象与数据格式

过程式代码(使用数据结构的代码)便于在不改动数据结构的前提下添加新函数(多态)

面向对象的代码便于在不改动现有函数的前提下添加新类

模块不应了解他所操作对象的内部情况,即不要暴露其内部结构

对象隐藏数据,暴露操作

方法不应调用由任何函数返回的对象的方法

数据传送对象DTO

六、错误处理

使用不可控异常(unchecked exception)

给出异常发生环境的说明

通过打包一个第三方API把异常抛出放到一个类中

用特例处理模式,你来处理特例,而不是用异常

不要返回和传递null

七、边界(使用第三方代码)

使用学习性测试,即边学习边测试

八、单元测试

TDD(测试驱动开发):(前期投入大,后期大幅减少开销)

在编写不能通过的单元测试前,不可编写生产代码

只可编写刚好无法通过的单元测试,不能编译也算不通过

只可编写刚好足以通过当前失败测试的生产代码

测试代码也需要整洁

为什么需要测试:任何修改都可能破坏代码,必须全面进行测试以确定修改成功

每个测试一个断言,一个概念

快速:测试应该快

独立:测试应该相互独立,不相互依赖

可重复:测试应该可以在任何环境中运行

自验证:测试应该有布尔值输出

及时:测试应及时编写

九、类

类应该从一组变量列表开始,公共静态变量、私有静态变量、私有实体变量

类应该短小,应该用25个单词描述一个类,且不用连接词,如若,与,或,但等

单一权责原则:类或模块应该只有一条加以修改的理由

高内聚:如果一个类中的每个变量都被每个方法所使用

开放-闭合原则:类应该对扩展开放,对修改封闭

十、系统

将系统的构造与使用分开,依赖注入,控制反转

测试驱动开发

考虑当前就足够了

十一、迭进

运行所有测试

重构

不可重复

表达力

尽可能少的类和方法

十二、并发编程

并发编程把目的与时机分解开,改进应用程序的吞吐量和结构

并发会在性能和编写额外代码上增加一些开销

正确的并发是复杂的,即使是简单的问题

并发缺陷并非总能实现

并发常常需要对设计策略进行根本性修改

并发防御原则:

分离并发相关代码与其他代码

谨记数据封装;严格限制对可能被共享的数据的访问

使用数据副本

线程尽可能独立

限定资源、互斥、

线程饥饿:一个或一组线程在很长时间内或永久被禁止,例如让执行块的线程先运行

死锁:每个运行的线程都拥有对象所要用的资源

活锁:执行次序一致的线程,每个都想起步,但发现其他线程已经在路上了,然后重复启动

执行模式

生产者-消费者模型:一个或多个生产者线程创建某些工作,并置于缓存或队列中。一个或多个消费者线程从队列中获取并完成这些工作。

读者-作者模型:当存在一个主要为读者线程提供信息源,但偶尔被作者线程更新的共享资源,吞吐量就会是个问题。要避免线程饥饿。

宴席哲学家:进程竞争资源。

避免使用一个共享对象的多个方法

保持同步区域微小

尽早考虑关闭问题

测试线程代码

不要将系统错误归咎于偶发事件

先使非线程代码可工作

编写可插拔的线程代码,能在不同的配置环境下运行

编写可调整的线程代码

运行于多处理器的线程

在不同平台上运行

装置试错代码:

硬编码:手工向代码中插入wait()、sleep()、yield()、priorty()的调用

自动化:使用工具

十三、总结与其他

一个源文件中应该尽量少用其他语言

一个函数应该实现其他程序员有理由期待的行为

程序应该有正确的边界行为,即在任何环境下都能运行

基类不要依赖派生类

不相互依赖的东西不应该耦合

类的方法只应对其所属类中的变量和函数感兴趣,不应该垂青其他类中的变量和函数

使用解释性变量

String key = match.getGroup(1);

String value = match.getGroup(2);

headers.put(key.toLowerCase(),value);

把逻辑依赖改为物理依赖

依赖者应该明确的询问被依赖者的全部信息。

避免否定性条件

不要掩蔽时序耦合

不要继承常量,而是使用import

0 0
原创粉丝点击