代码整洁之道读书笔记

命名

  • 名副其实:避免出现命名模糊,应做到见名知其意
// bad naming
 func getThem() -> [Int] {
        var list: [Int] = []
        for x in 0...99 {
            list.append(x)
        }
        return list
  }
    // good naming
   func getFlaggedCells() {
        var cells: [Int] = []
        let gameBoard = 0...99
        for cell in gameBoard {
            cells.append(cell)
        }
        return cells
    }
  • 避免误导: 比如前后拼写不一致
/// bad
func testName() {
        var a = 1
        let o = 1
        let o1 = 2
        let I = 2
        if o == 1 {
            a = o1
        } else {
            I = o1s
        }
    }
  • 做有意义的区分,读者能够通过命名就能分别出两个方法之间的区别
  • 使用读得出来的名称,不要造词


  • 使用可搜索的名称,比如避免使用magic number


  • 不推荐使用成员前缀
  • 避免思维映射:不应当让读者在闹中把你的名称翻译为他们熟知的名称
  • 类名:类名应该是名词,不应当时动词
  • 方法名:应当是动词或者动词短语,eg: postPayment, delelePage
  • 避免同一个单词用于不同目的
  • 使用用专业术语命名
  • 添加有意义的语境:主要用于拆分大函数

函数

  • 目标:如何构建让读者一看就明白的函数
  • 短小:函数的第一个规则就是短小
  • 一个函数只做一件事:函数应该值做一件事,做好这件事,只做一件事。判断一个函数是否只做了一件事:就是看是否能够再拆出一个函数。
  • 使用描述性的名称定义函数
  • 函数参数:最理想的是零参数,其次是一个参数,两个参数,。。。如果要函数要对输入参数进行转换操作,转换结果就该体现为返回值
  • 标识参数:标识参数丑陋不堪。reader(Boolean isSuite) 可以写为renderForSuite()和renderForSingleTest()
  • 二元函数(两个参数的函数):可以使用一些机制将其转换为一元函数 writeField(outputStream, name) => outputStream.writeField(name)
  • 三元函数(三个参数):应转换为参数对象
  • 参数对象:函数中有三个及以上的参数,应将他们封装为对象
  • 动词与关键字:函数和参数应当形成一种非常良好的动词/名词对形式
  • 无副作用:一个函数只做一件事,eg:一个做加法的函数,却在函数内部修改了全局变量
  • 分隔指令与询问:指令与询问分隔开来,防止混淆的发生
// 错误的
if (set("username", "bob")) ...

// 正确的
if (attributeExist("username") {
  setAttribute("username", "bob")
}
  • 使用异常替代返回错误码
  • 抽离tryCatch代码块
  • 错误处理就是一件事:错误处理的函数只做错误处理,不做其他事
  • 别重复自己:比如避免类似于这种写法:Setup ,SuiteSetup, TeadDown, SuiteTearDown
  • 结构化编程

注释

  • 注释不能美化糟糕的代码:带有少量注释的整洁而有表达力的代码,要比带有大量注释的零碎而复杂的代码像样得多,不能因为代码很糟糕而通过写注释来解释
  • 有代码来阐述:很多时候,简单到只需要创建一个描述与注释所言同一事物的函数即可
  • 好注释包含哪些:
    • 法律信息
    • 提供信息的注释
    • 对意图的解释
    • 阐述:注释某些晦涩难明的参数或返回值的意义翻译为某种可读形式
    • 警示:用于警告其他程序员会出现某种后果的注释也是有用的
    • TODO注释:是一种程序员认为应该做的,但是由于某种原因目前还没做的工作
    • 放大:注释可以用来放大某种看来不合理之物的重要性
  • 坏的注释有哪些:
    • 楠楠自语
    • 多余的注释
    • 误导性的注释
    • 循规式注释
    • 日志型注释
    • 废话注释
    • 位置标记
    • 括号后面的注释:会破坏函数结构
    • 归属于署名:最好使用代码版本控制来处理归属
    • 注释掉的代码:直接把代码删掉即可

格式

  • 格式的目的:关乎团队沟通,增强代码的可读性,可读性会影响到代码的可维护性和扩展性
  • 垂直格式
    • 决定了代码文件的行数
    • 向报纸学习:头条主题 -> 大纲 -> 概述 -> 故事细节。篇幅:短小精悍,有些稍微有点长,
  • 概念间垂直方向上的区隔
  • 垂直方向上的靠近
  • 垂直距离
    • 变量声明,应尽可能靠近其使用位置
  • 实体变量:应该在类的顶部声明
  • 相关函数:调用者函数应该尽可能放在被调用者上面
  • 概念相关:概念相关的代码应该放到一起,相关性越强,彼此之间的距离就应该越短
  • 垂直顺序
  • 决定了代码的宽度
  • 横向格式:代码行长度控制在100到120个字符之间
  • 水平方向的区隔与靠近
  • 水平对齐:推荐不水平对齐,不推荐C++的那种水平对齐方式
  • 缩进:类中的方法相对改类缩进一个层级,方法的细实现相对方法声明缩进一个层级,代码块的事项相对于容器代码块缩进一个层级

对象和数据结构

  • 数据抽象:不愿保罗数据细节,更愿意以抽象形态表述数据
  • 数据,对象的反对称性
    • 过程式代码便于在不改动既有数据结构的前提下添加新函数,面向对象代码便于在不改动既有函数的前提下添加新类

错误处理

  • 当错误发生时,程序员就有责任确保代码照常工作
  • 使用异常而非返回码:如果使用返回码:调用者必须在调用之后即刻检查错误,但是这个步骤很容易被遗忘。如果是抛出异常,调用代码就被编译识别出来,不如不处理异常就编译不通过
  • 先写try-catch-finally
  • 使用不可控异常
  • 给出异常发生的环境说明
  • 依调用者需要定义异常类:便于被捕获
  • 别返回null值
  • 别传递null值

单元测试

  • TDD三定律
    • 定律一:在编写不能通过的单元测试前,不可编写生产代码
    • 定律二:只可编写刚好无法通过的单元测试,不能编译也算不通过
    • 定律三:只可编写刚好足以通过当前失败测试的生产代码
  • 保持测试整洁:测试代码和生成代码一样重要,它需要被思考,被设计和被找了,它应该想生成代码一般保持整洁。测试越脏,代码就会变得越脏。最终,丢了测试,代码开始腐败
  • 整洁的测试
    • 三个要素:可读性,可读性,可读性
    • 测试的三个环节:构造-操作-检验 (BUILD-OPERATION-CHECK)
  • 每个测试一个断言:单个测试中的断言数量应该最小化
  • 每个测试一个概念
  • 最佳规则:应该尽可能减少每个概念的断言数量,每个测试函数只测试一个概念
    • FIRST:
      • 快速Fast:测试应该足够快
      • 独立Independent:测试应该相互独立
      • 可重复性repeatable:测试在任何环境中重复通过
      • 自足验证Self-Validating:测试应该有布尔值输出
      • 及时Timely:测试应及时编写

  • 类应该短小
  • 单一权则原则:类和模块应有且只有一条加以修改的理由
  • 内聚:类应该只有少量实体变量。类中的每个方法都操作一个或多个这种变量,通常而言,方法操作的变量越多,就越粘聚到类上。如果一个类中的每个变量都被每个方法所使用,则该类具有最大的内聚性。
  • 为了修改而组织:在整洁的系统中,我们对类加以组织,以降低修改的风险。在理想系统中,我们通过扩展系统而非修改现有代码来添加新特性
  • 隔离修改:接口代替类

系统

  • 将系统的构造与使用分开:软件系统应将启动过程和启动过程之后的运行时逻辑分离开,在启动中构建应用对象,也会存在互相缠结的依赖关系
  • 分解main函数:将构造与适使用分开的方法之一是将全部构造过程搬迁到main或称之为main的模块之中。main函数创建系统所需的对象,再传递给应用程序,应用程序只管使用。
  • 工厂:使用抽象工厂模式让应用程雪控制何时创建,但构造的细节却隔离与应用程序之外
  • 依赖注入(DI):分离构造与使用,在依赖管理情景中,对象不应该负责实例化对自身的依赖,应该将这份权责移交给其他”有权力”的机制,从而实现控制的反转
  • 扩容:架构都可以递增式地增长,只要我们持续将关注面恰当地切分
  • 测试驱动系统架构:最佳的系统架构由模块化的关注面领域组成,每个关注面均用纯Java对象实现,不同的领域之间最不具有侵害性的方面或类方面工具整合起来,这种架构能测试驱动,就像代码一样

迭进

  • 简单设计的四条原则

    • 运行所有测试
    • 不可重复
    • 表达程序员的意图(保证表达力)
    • 尽可能减少类和方法的数量
  • 简单设计规则1:运行所有的测试

    • 全面测试并持续通过所有测试的系统,就是可测试的系统
    • 遵循有关编写测试并持续运行测试的简单,明确的准则,系统就会更贴近低耦合度,高内聚的目标。编写测试引致更好的设计
    • 测试消除了对清理代码就会破坏代码的恐惧
    • 通过实例起到文档作用
  • 简单设计规则2~4:重构

    • 重构过程中,可以应用有关优秀设计的一切知识。提升内聚性,降低耦合度,切分关注面,模块化系统性关注面,缩小函数和类的尺寸,选用更好的名称。
  • 不可重复:重复是拥有良好设计系统的大敌。它代表着额外的工作,额外的风险和额外且不必要的复杂度。

  • 表达力:下一位读代码的人最有可能是自己。选用较好的名称,将大函数切分小函数,时时照拂自己创建的东西。用心是最珍贵的资源

  • 极可能少的类和方法(优先级最低)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容