代码整洁之道

一、勒布朗法则——稍后等于用不

二、不该该羞于告知本身的想法

咱们可能把混乱的代码归咎于专一于项目进度的产品经理、苛求的用户,可是实际上是咱们太不专业了。 对于不合理的要求咱们应该提出来,多数经理想要知道实情,即使他们看起来不喜欢实情。多数经理想要好代码,即使他们老是痴迷于进度。他们会奋力卫护进度和需求,那是他们应该干的。所以咱们也应当以一样的热情卫护代码java

1、有意义的命名

三、代码块要尽可能小

实际上,从有软件起人们就在反复强调这一点。越小越好。程序员

四、命名要尽可能名副其实

  • 变量、函数或类的名称应该已经答复了全部的大问题。
  • 不要惧怕名称过长。
  • 选个好名字要花时间,但省下来的时间比花掉的多。
  • 一旦有更好的名称,就换掉旧的。

五、命名要避免误导

  • 应当尽可能避免使用与本意相悖的词。
  • 别用accountList来指称一组帐号,除非他真的是List类型。List一词对程序员有特殊意义。若是包纳帐号容器并不是真是个List,除非他真的是List类型。即便容器就是个List,最好也别再名称中写出容器名。甚至直接用accounts都会好一些。(PHP应该没这些要求吧)
  • 类似的名称就别用了

六、废话就是冗余

命名中尽可能避免废话。bash

七、命名要尽可能使用读得出来的名称

人类长于记忆和使用单词。数据结构

八、定义常量!!!!

方便查找和修改。app

九、避免思惟映射

循环计数器天然有可能被命名为i或j或k(但千万别用字母I),这是由于传统上惯用但字母名称作循环计数器。 其余状况下最好就别用了。函数

十、类名应该是名词,如Customer,而不该该是动词。

十一、方法名应当是动词或动词短语。

十二、每一个概念对应一个词

controller这种名字相似的单元测试

2、函数

1三、短小

  • 函数的第一规则是要短小
  • 函数的第二条规则还要更短小

1四、只作一件事

函数应该作一件事。作好这件事。只作这一件事。 要判断韩式是否不止作了一件事,有一个方法,就是看是否能再拆出一个函数,改函数不只是单纯的从新诠释其实现。测试

1五、每一个函数一个抽象层级

抽象层级是个什么概念呢? 如: getHtml()算是较高抽象层 String pagePathName = PathParser.render(pagePath) 算是中间抽象层 .append("\n") 算是至关低的抽象层ui

1六、 switch 语句

  • 确保每一个switch都埋藏在较低的抽象层级,并且永远不重复
  • 单一权责原则 简单说,就是一个类负责一个职责。
  • 开放闭合原则 软件实体(类、模块、函数等等)应该能够扩展,可是不可修改。
  • 尽量抽象 示例
public Money calculatePay(Employee e)
throws InvalidEmployeeType {
   switch (e.type) {
        case COMMISSIONED:
            return calculateCommissionedPay(e);
        case HOURLY:
            return calculateHourlyPay(e);
        case SALARIEED:
            return calculateSalariedPay(e);
        default:
            throw new InvalidEmployeeType(e.type);
        }
}
复制代码

上述代码可能处处都有相似结构的函数。多是isPayday(Employee e, Date date)或deliverPay(Employee e, Date date);this

解决方案就是:**将switch语句埋到抽象工厂地下,不让任何人看到。该工厂使用switch语句为Employee的派生物建立适当的实体,而不一样的函数,如calculatePay、isPayday和deliverPay等,则藉由Employee接口多态的接受派遣。

1七、 函数参数

  • 参数尽可能要少 最理想的参数数量是零(零参数函数),其次是一(单参数函数),再次是二(双参数函数),应尽可能避免三(三参数函数)。有足够特殊的理由才能用三个以上参数(多参数函数)。——因此不管如何也不要这么作。 若是函数看起来须要两个、三个或三个以上参数,就说明其中一些参数应该封装为类了。

1八、无反作用

什么是反作用? 反作用是函数只承诺作一件事情,但仍是作其余被藏起来的实情。 若是咱们忽略了,就作了可能咱们并不指望的事情。

1九、输出参数

static void appendFooter(StringBuilder sb) {
        sb.append("Here you go!");
    }
复制代码

咱们应该尽可能避免使用appendFooter(s)这样的用法。应尽可能使用report.appendFooter()方法。 由于咱们会浪费检查函数声明的时间。 面向对象语言中对输出参数大部分的需求已经消失了,由于this也有输出函数的意味在内。

20、使用异常代替返回错误码

缘由:在深层次的嵌套结构中,当返回错误码的时候,要求当即处理错误。 使用异常的话,错误处理代码就能从主路径代码中分离出来,获得简化。

2一、抽离Try/Catch代码块

Try/Catch代码块丑陋不堪。他们搞乱了代码结构,把错误代码处理与正常流程混为一谈。最好把try 和 catch 代码块的主体部分抽离出来,另外造成函数。

2二、错误处理就是一件事

函数应该只作一件事。错误处理就是一件事。

2三、Error.java 依赖磁铁

返回错误码一般暗示某处有个类或是枚举,定义全部错误码。 若是使用它,Error枚举修改时,全部这些其余的类都须要从新编译和部署。这对Error类形成了负面压力 ===》程序员就使用旧的错误码,不肯意增长新的错误代码。 使用异常替代错误码,新异常就能够从异常类派生出来。无需从新编译或从新部署。

2四、别重复本身!!!

不要写重复代码 重复代码会增长忽略错误的可能性

3、注释

注释说明咱们代码写的并很差。 可是咱们有时候又必需要写注释。 可是程序员又不会及时维护注释,因此随着时间流逝,注释离所描述的代码愈来愈远。 惟一真正好的注释是你想办法不去写的注释 用整理代码的决心替代创造废话的冲动。

2五、警示注释

2六、TODO注释

2七、括号后面的注释

//while //try 相似的 这对于深层嵌套颇有意义 可是咱们为何不写更小的、封装的函数呢?

2八、注释掉的代码

直接把代码注释掉是讨厌的作法。别这么干!!!(我作了 55555~) 可能的缘由是:1⃣️不敢删除2⃣️用于提示3⃣️…… 可是这些都不能否认混乱了代码 如今的源代码控制系统已经保证代码丢不了了,删除便可

4、格式

先明确一点,代码格式很重要,代码格式不可忽略,必须严肃对待。(以前的我…………)

2九、概念间垂直方向上的区隔

在封包声明、导入声明、每一个函数等等之间。有空白行隔开。这条极其简单的规则很是有利于代码阅读。

30、垂直方向上的靠近

有紧密关系的代码应该靠近,方便阅读理解。

3一、垂直距离

  • 关系密切的概念应该互相靠近,有助于理解系统作什么。而不是把时间和精力找到和记住代码碎片在哪里。(除非有很好的理由放到不一样的文件中)
  • 变量声明 应该尽量靠近其使用的位置。
  • 实体变量 实体变量应该在类的顶部声明。
  • 相关函数 若某个函数调用另一个,就应该把他们放在一块儿,并且调用者应该尽量发在被调者上面。
  • 概念相关 概念相关的代码应该放到一块儿。相关性越强,彼此之间的距离就该越短。

3二、横向格式

应该尽可能保持代码行短小。 能够遵循一个原则:无需拖动滚动条到右边的原则。

5、对象和数据结构

对象暴露行为,隐藏数据。便于添加新对象类型而无需修改既有行为。同时也难以在既有对象中添加新行为。数据结构暴露数据,没有明显的行为,便于向既有数据结构添加新行为,同时也难以向既有函数添加新数据结构。

6、错误处理

错误处理很重要,但若是他搞乱了代码逻辑,就是错误的作法

3三、使用异常而非返回码

若是使用了错误码,调用者必须在调用以后即刻检查错误。不幸的是,这个步骤很容易被遗忘。

3四、先写Try-Catch-Finally语句

异常的妙处之一是,他们在程序中定义了一个范围 执行try-catch-finally语句中try部分的代码时,是在代表可随时取消执行,并在catch语句中继续 在编写可能抛出异常的代码时,最好先写出try-catch-finally语句。这能帮你定义代码的用户应该期待什么。不管try代码块中执行的代码出什么错都同样

3五、使用不可控异常

  • 可控异常的代价是违反了开放/闭合原则
  • 若是你在方法中抛出可控异常而catch语句在三个层级之上,你就得在catch语句和抛出异常处之间的每一个方法签名中声明该异常
  • 以此类推,最终获得的就是一个从软件最底端贯穿到最高端的修改链。
  • 可控异常以这种方式破坏封装简直是一种耻辱
  • 对于通常的应用开发,可控异常的依赖成本要高于收益。

3六、给出异常发生的环境说明

有助于判断错误的来源和处所

3七、依调用者须要调用异常类。

举例说明:

ACMEPort port = new ACMEPort(12);

try {
    port.open();
 } catch (DeviceReesponseeException e) {
    reportPortError(e);
    logger.log("Device response exception", e);
} catch (ATM1212UnlockedException e) {
    reportPortError(e);
    logger.log("Unlock exception", e);
} catch (GMXError e) {
    reportPortError(e);
    logger.log("Device response exception");
} finally {
...
}
复制代码

上述语句包含了一大堆重复的代码。 咱们能够将new port 和 异常处理打包一个新的函数。

好的作法是将第三方API打包。当你打包一个第三方API,你就下降了对他的依赖:将来你能够不太痛苦的改用其余代码库。在你测试本身的代码时,打包也有助于模拟第三方调用

3八、别返回null 值

3九、别用null值

7、单元测试

40、TDD三定律

TDD是**测试驱动开发**(Test-Driven Development)的英文简称,是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码以前,先编写单元测试用例代码,测试代码肯定须要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不仅适用于XP(Extreme Programming),一样能够适用于其余开发方法和过程。

  • 定律一 在编写不能经过的单元测试前,不可编写生产代码。
  • 定律二 只可编写恰好没法经过的单元测试,不能编译也算不经过。
  • 定律三 只可编写恰好足以经过当前失败测试的生产代码。
相关文章
相关标签/搜索