何为整洁
5S哲学
- 整理 seiri 或谓组织
- 整顿 seiton 或谓整齐
- 清楚 seiso 或谓清洁
- 清洁 seiketsu 或谓标准化
- 身美 shitsuke 或谓纪律(自律)
主要句子
- 整洁近乎虔诚 Cleanliness is next to godliness
- Test Obsessed 沉迷测试
整洁的代码怎么产生的
定义
- 整洁即优雅
- 整洁的代码是由某位特别在意它的人写的,几乎无任何改进的余地
- 能通过所有测试
- 没有任何重复代码 =最重要=
- 体现系统中的全部设计理念
- 包括尽可能少的实体,比如类、方法、函数等
自我总结
- 1.消除重复
- 2.提高代码自我表达能力(一定程度少依赖注释)
任何门派都绝非正确。不过,身处某一门派,我们须全身心善技,排斥其他门派,学有所成后再转投其他门派,扩展自己的知识和技能
童子军军规
- 让营地比你来的时候更干净
最好你经受过的代码都比你刚接手的时候更整洁
命名与函数
命名
- 名副其实
- 如果名称需要注释来补充,那就不算名副其实
- 避免误导
- 做有意义的区分
- 使用读的出来的名称
- 使用可搜索的名称
- 更改变量时,一键搜索就可以找到所有
- 避免使用编码
- 避免思维映射
- 别扮可爱
- 言到意到, 意到言到
- 每个概念对应一个词
- 别用双关语
- 避免将同一个词用于不同目的。同一术语不同概念即双关语
- 使用解决方案领域名称
- 使用源自问题领域的名称
- 添加有意义的语境
- 不要添加没用的语境
函数
- 短小
- 函数的第一规则是短小,第二规则是更短小
- 20行封顶最佳
- 只做一件事
- 函数应该做一件事。做好这件事。只做这件事
- 检测是否做一件事:看其能否继续拆分
- 每个函数一个抽象层级?
- switch语句?
- 使用描述性的名称
- 函数参数
- 最理想的参数数量是0,其次是1,再次是2
- 无副作用
- 分割指令与询问
- 函数要么做什么事,要么回答什么事,二者不可兼得
- 函数应修改某对象的状态或是返回改对象的有关信息
- 使用异常替代返回错误码
- 抽取try/catch代码块
- 最好把try/catch代码块抽取出来,另外形成函数
- 将处理整体,try,catch三部分放在一个函数内,形成三个子函数部分
- 错误处理就是一件事
- error错误码统一处理
- 抽取try/catch代码块
- 别重复自己
- 结构化编程
- 如何写出这样的函数
- 先写后打磨
“我写函数时,一开始都冗长而复杂。有太多缩进和嵌套循环。有过长的参数列表。名称是随意取的,也会有重复代码。不过我会配上一些单元测试,覆盖每行丑陋的代码。然后我会打磨这些代码,分解函数、修改名称、消除重复。我缩短和重新安置方法。有时我还拆散类。同时保持测试通过”
“我并不从一开始就按照规则写函数。我想没人做得到”
函数是语言的动词,类是名词
注释与格式
注释
- 别给糟糕的代码加注释,重新写吧
- 注释是一种必须的恶,是弥补代码表达意图时遭遇的失败
- 注释不能美化糟糕的代码
- 用代码来阐述
- 语义化简单判断函数
- 好注释
- 法律信息
- 提供信息的注释
- 对意图的解释
- 阐释
- 警示
- ToDo注释:解释为何无所作为,将来会产生什么影响
- 放大:放大某种看来不合理之物的重要性
- 公共API中的解释性语句
- 坏注释
- 喃喃自语
- 多余的注释
- 误导性注释
- 循规式注释:比如自带的函数注释,要写函数名、作用、值…
- 日志式注释
- 废话注释
- 可怕的废话
- 能用函数或变量时就别用注释
- 位置标记 长长的/和****
- 括号后面的注释:破坏代码可读性,注释应独立成行
- 归属与署名:写上日期和姓名看起来很纯。版本控制器会说明一切
- 注释掉的代码:就像没丢掉的垃圾
- html格式的注释
- 非本地信息:文不对码
- 信息过多+废话过多
- 不明显的联系:注释和代码联系不紧密
- 函数头:短函数好名字比注释强多了
- 非公共API中的解释性语句
格式
- 我大多数小于200多行,没有一个超过500行的单个文件完全可以构造一个出色的系统
垂直格式
- 向报纸学习
- 大纲:入口
- 头部:必用部分
- 主题:核心逻辑
- 尾部:可能用部分
- 概念间垂直方向的间隔
- 适当的利用空格间隔不同函数,不同类
- 垂直方向上的靠近
- 紧密相关的代码、变量定义应该相互靠近
- 垂直距离
- 变量生命应尽可能靠近其使用位置,本地变量应在函数顶部
- 实体变量应在类的顶部
- 概念相关的代码应该放在一起
- 垂直顺序
- 自上而下:被调用者放在执行调用的函数下面,建立自顶向下贯穿源码代码模块的良好信息流
把最重要的概念先出来,并包含最少的细节来描述他,底层细节最后出来,让旁观者从最初的几个函数获知要旨,而不至于沉溺细节
横向格式
- 正常代码程度应在80字符以内,上限120个字符
- 利用空格将相关性较弱的事物分开(如运算符的左右部分,for循环中的语句)
- 保持一定程度的水平对齐(上下)
- 必要的缩进
- 空范围(while中无语句也要加大括号)
- 制定统一团队风格
对象和数据结构
将对象设置为私有有一个理由:我们不想其他人依赖这些变量。我们还想在心血来潮时能自由修改其类型或实现
前端暂时我没有用到类,现在看这部分还很迷
- 数据抽象
- 数据、对象的反对称性
- …
错误处理
错误处理的存在在于,前端不准用户看到报错;有些错误可能导致程序崩溃、影响下一步运行
错误处理很重要,但如果它搞乱了代码逻辑,就是错误的做法
- 使用异常而非返回码=没搞懂=
- 先写Try-Catch-Finally语句
- 所有try的范围,只在可能出错的最小集合集中使用
- 别让用户察觉异样
- 使用不可控异常
- 可控异常的代价就是违反开放/闭合原则。如果你在方法中抛出可控异常,而catch语句在三个层级之上,你就得在catch语句和抛出异常处之间的每个方法签名中声明该异常。这意味着对软件中低层级的修改,都将波及较高层级的签名。修改好的模块必须重新构建、发布,即便它们自身所关注的任何东西都没改动过。
- 你应该创建信息充分的错误信息,并和异常一起传递出去,在消息中,包括失败的操作和失败类型。
- 给出异常发生的环境说明
- 如果你的应用程序有日志系统,传递足够的信息给catch块,并记录下来
- 依调用者需要定义异常类
- 定义常规流程
- 针对常规异常:创建一个类或配置一个对象,用来处理特例。将异常行为封装到特例对象中。
- 别返回null值
- js如何防止接口返回空值,或不存在字段
如果将错误处理隔离看待,独立于主要逻辑之处,就能写出强固而整洁的代码
如何整理混乱的代码
说完如何保持整洁的代码,如果遇到了一团混乱的代码,我们要如何将它整理的井井有条呢?首先我们要能够明确的找到混乱地方,我们就要像剥洋葱一样一点一点的拆解代码,小幅的进行改动。每次改动,都有前边提到的测试来保证我们并没有破坏现有的功能。
当我们要整理一大坨代码的时候,个人经验,如果不知道如何改动的时候,可以先从最基本的入手,看懂一段代码并且明确这是做了一件事之后,提取出来,取一个具有描述意义的名字。当将代码这样拆解成一个一个的方法之后,结构就清晰了很多。之后我们就会闻到很多的code smell,发现很多的重复。关于如何发现和解决code smell,可以参考《重构》这本书,这本书列举了很多的code smell,并且给出了很好的解决方案。