代码整洁之道
2018-06-05 15:37:15 139 举报
AI智能生成
代码整洁之道思维导图分享
作者其他创作
大纲/内容
序与概述
小处诚实非小事:以小见大,注重细节
建筑中最细小的部分,比如关不紧的门,都将整个大局的魅力毁灭殆尽
建筑中最细小的部分,比如关不紧的门,都将整个大局的魅力毁灭殆尽
认真对待每个变量名:当为自己孩子起名般的谨慎给变量命名
不要过早放弃在代码上的工作:
我们经常关注外在的表现甚于关注要交付之物的本质
我们经常关注外在的表现甚于关注要交付之物的本质
制造上的返工导致成本上升,重做设计却创造价值
稍后等于永不
做有代码感的程序员:
缺乏代码感的程序员,看混乱是混乱,无处着手;
有代码感的程序员能从混乱中看出其它的可能与变化
缺乏代码感的程序员,看混乱是混乱,无处着手;
有代码感的程序员能从混乱中看出其它的可能与变化
糟糕的代码引起混乱:
别人修改糟糕的代码时,往往越改越乱
别人修改糟糕的代码时,往往越改越乱
整洁的代码总是看起来像是某位特别在意它的人写的:
几乎没有改进的余地,代码作者什么都想到了,如果你企图改进它,总会回到原点
几乎没有改进的余地,代码作者什么都想到了,如果你企图改进它,总会回到原点
童子军军规:让营地比你来时更干净
对象和数据结构
数据抽象:以抽象的形态表述数据,不是用接口或 setter、getter 就万事大吉,需做认真的思考
得墨忒耳律:模块不应了解它所操作对象的内部细节
单元测试
TDD三定律
保持测试整洁:如果测试不能保持整洁,就会失去他们,同时会失去保证生产代码可扩展的元素
整洁的测试:可读性、可读性、可读性
每个测试一个断言:每个测试函数只测试一个概念
FIRST
快速 Fast:测试应该能快速运行
独立 Independent:测试应该相互独立
可重复 Repeatable:应当可以在任何环境中重复通过
自足验证 Self-Validating:测试应该有布尔值输出,不应该查看日志文件来确认是否通过
及时 Timely:测试应及时编写
迭进
表达力
写出自己能理解的代码很容易:
因为在写这些代码时,我们正深入于要解决的问题;代码的其它维护者不会那么深入,也就不易理解代码
因为在写这些代码时,我们正深入于要解决的问题;代码的其它维护者不会那么深入,也就不易理解代码
单元测试的代码也该具有良好的表达性:
测试的主要目的就是通过实例起到文档的作用,读到测试的人应该能很快理解某个类是做什么的
测试的主要目的就是通过实例起到文档的作用,读到测试的人应该能很快理解某个类是做什么的
尽可能少的类和方法:
有时类和方法太多是由于教条主义导致的
有时类和方法太多是由于教条主义导致的
味道与启发
注释只应该描述有关代码和设计的技术性信息:
不要注释可以由代码控制系统保存的信息
不要注释可以由代码控制系统保存的信息
注释掉的代码污染了所属的模块,分散了阅读者的注意力
如果函数非要修改什么东西的状态不可,就修改它所在对象的状态好了
最小惊异原则:
函数或类应该实现其他程序员有理由期待的行为,如果明显的行为未被发现,阅读者就不能依靠他们对函数名称的直觉,不得不阅读代码细节
函数或类应该实现其他程序员有理由期待的行为,如果明显的行为未被发现,阅读者就不能依靠他们对函数名称的直觉,不得不阅读代码细节
关闭失败的测试,告诉自己过后处理,这和假装刷信用卡不用还钱一样坏
变量和函数应该在靠近被使用的地方定义
使用多个函数,通常优于向单个函数传递更多参数来选择函数行为
让程序可读的最有力方法之一就是将计算过程打散成一系列良好命名的中间值
有人硬塞进足够多的 if 语句和标识,从不真正停下来考虑发生了什么,勉强让系统能工作
魔术数,泛指一切不能自我描述的符号,例如:a,b
否定式比肯定式难明白一些,尽可能将条件表示为肯定式
如果结构自始至终保持一致,其他人就会使用它并遵守其约定
不要让某个模块了解太多其协作者的信息:
A与B协作,B与C协作,不要让A了解太多C的信息
A与B协作,B与C协作,不要让A了解太多C的信息
常量躲在了继承的最顶端:
这时应该使用静态导入,或者在常量前加上类名,保持常量可追溯
这时应该使用静态导入,或者在常量前加上类名,保持常量可追溯
与项目有关的特定意义的名称用的越多,代码读起来就越容易明白
名称的作用范围越大,名称就该越长、越明确
不要用简单的动词来描述做了不止一个简单动作的函数
缺陷倾向于扎堆,在某个函数中发现一个缺陷时,最好全面测试那个函数,可能会发现不止一个缺陷
让测试尽量快:
慢速的测试是不会被运行的测试,时间一紧,较慢的测试就会被摘掉
慢速的测试是不会被运行的测试,时间一紧,较慢的测试就会被摘掉
有意义的命名
名副其实:它该告诉你,它为什么会存在,它做什么事,应该怎么用,
如果名称需要注释来补充,那就不算是名副其实
如果名称需要注释来补充,那就不算是名副其实
避免误导:误导性名称真正可怕的例子,是用小写字母 l和大写字母O作为变量名,或名称的一部分
做有意义的区分
使用读得出来的名称
使用可搜索的名称
避免使用编码:Java不需要在命名时使用类型编码(匈牙利命名法),那都是C语言的产物,
因为对象是强类型的,编辑环境在编译前就能侦测到类型错误
因为对象是强类型的,编辑环境在编译前就能侦测到类型错误
避免思维映射
方法名
使用动词
重载构造器时,使用描述了参数的静态工厂方法,例如:
Complex fulPoint = Complex.fromRealNumber(23)
Complex fulPoint = Complex.fromRealNumber(23)
别扮可爱
每个概念对应一个词
别用双关语:代码写得让别人一目了然,而不必殚精竭虑地研究,要使用大众化的表达
使用解决方案领域名称
使用源自所涉问题领域的名称
添加有意义的语境
不要添加没用的语境:只要短名称足够清楚,就比长名称好,别给名称添加没用的语境
函数
短小:不应该大到足以容纳嵌套结构;缩进层级不该多于一层或两层
只做一件事:
只做该函数名下同一抽象层上的事情;有时将if拆出来的函数,只是重新诠释代码,并未改变抽象层级。
判断是否不止做了一件事,就是看能否再拆出一个函数,该函数不仅只是单纯地重新诠释其实现。
只做该函数名下同一抽象层上的事情;有时将if拆出来的函数,只是重新诠释代码,并未改变抽象层级。
判断是否不止做了一件事,就是看能否再拆出一个函数,该函数不仅只是单纯地重新诠释其实现。
每个函数一个抽象层级:让代码读起来像是一系列自顶向下的TO起头段落
使用描述性的名称
函数越短小,功能越集中,越容易起个好名称
长而具有描述性的名称,比短而令人费解的名称好
选择描述性名称能理清你关于模块的设计思路
追索好名称往往导致对代码的重构
函数参数
向函数传入布尔值简直丑陋不堪:可考虑新建一个函数
三个参数要比两个参数难懂的多,排序、忽略、琢磨的问题都会加倍体现
如果函数需要两个或三个以上的参数,可以考虑其中的一些参数封装为类
无副作用:时序性耦合
例如修改密码的方法里进行cookie设置,那么这个方法只能在特定的时刻调用,
如果在不合适的时候调用,会话数据就会沉默地丢失。
例如修改密码的方法里进行cookie设置,那么这个方法只能在特定的时刻调用,
如果在不合适的时候调用,会话数据就会沉默地丢失。
分隔指令与询问
使用异常代替返回错误码:如果try在函数内存在,那么它应该是这个函数的第一个单词,
并且catch/finally后面也不该有其他内容。
并且catch/finally后面也不该有其他内容。
别重复自己
结构化编程
如何写出这样的函数:先想什么就写什么,然后再不断地打磨,并配合单元测试
编程艺术就是语言的艺术,大师级程序员把系统当故事来讲,而不是当程序来写
注释
注释不能美化糟糕的代码:别给糟糕的代码加注释,重新写吧
用代码来阐述:如果发现需要写注释,试试用代码来表达
好注释
法律信息
对意图的解释
阐释
把某些晦涩难明的参数或返回值翻译为可读的形式
注释某个标准库的参数或返回值
坏注释
每个函数都要有 javadoc 或每个变量都要有注释是愚蠢的
如果想标记右括号,其实应该缩短函数
如果一定要写注释,确保它描述的是离它最近的代码
类
类的组织:自顶向下,让程序读起来像是一篇文章;
从一组变量列表开始:公共静态常量->私有静态变量->私有实体变量;
变量列表之后应该是公共函数,然后是私有函数
从一组变量列表开始:公共静态常量->私有静态变量->私有实体变量;
变量列表之后应该是公共函数,然后是私有函数
类应该短小
拥有巨大、多目的类的系统,总是让我们在目前并不需要了解的一大堆东西中艰难跋涉
如果有些函数需要共享某些变量,可以为这些函数建立新类
将大函数拆分为小函数,往往也是将类拆分为多个小类的时机
为了修改而组织
类应当对扩展开放,对修改封闭
依赖倒置原则:类应当依赖于抽象而不是依赖于具体细节
收藏
收藏
0 条评论
下一页