代码规范

基本方法用下划线隔开的方式程序员

类名用大驼峰web

变量用小写算法

路径变量大写数据库

  1. 一切代码与注释都是有实际意义的,没有冗余,整洁干净
  2. 代码能经过全部测试,运行高效
  3. 命名名副其实,区分清晰,意义明了,尽可能作到看名字就能知道你的意图
  4. 代码逻辑尽可能直白,简单
  5. 每一个方法只作一件事,功能明确且单一,方法间井井有条
  6. 每一个类职责尽可能单一,高内聚,类与类之间低耦合
  7. 测试覆盖面广,每一个测试用例基本只测一个点
  8. 测试代码的要求与业务代码同样高编程

一.整洁代码

整洁代码的一些特征安全

代码逻辑应该直接了当,叫缺陷难以隐藏;数据结构

尽可能减小依赖关系,使之便于维护;多线程

依据某种分层战略完善错误处理代码;架构

性能调至最优,免得引诱别人作没规矩的优化,搞出一堆混乱来;并发

整洁的代码只作好一件事;

有单元测试和验收测试;

有意义的命名;

尽可能“少”;

两条重要原则:

尽可能让代码易读,开发时减小读的时间。

童子军军规:“让营地比你来时更干净”。

二.有意义的命名

名副其实

避免误导

1.程序员必须避免留下掩藏代码本意的错误线索,应当避免使用与本意相悖的词

2.以一样的方式拼写出一样的概念才是信息,拼写先后不一致就是误导

3.要注意使用小写字母i和大写字母O做为变量名,看起来像“壹”和“零”

作有意义的区分

1.不一样东西意义不同时,必定要在命名上区分,如变量,不要简单的cat1,cat2这样区分

命名读得出来,单词可搜索

避免使用编码

1.不要乱用前缀

避免思惟映射

1.明确是王道,不要让人须要想象或者产生联想

类名是名词或名词短语,方法名是动词或者动词短语

别扮可爱

别用双关语

1.避免将同一单词用于不一样目的

2.应尽力写出易于理解的代码,把代码写得让别人能一目尽览而没必要殚精竭虑地研究

使用解决方案领域名称,使用源自所涉问题领域的名称

添加有意义的语境

1.你须要用有良好命名的类、函数或名称空间来放置名称,给读者提供语境

2.若是没这么作,给名称添加前缀就是最后一招了

不要添加没用的语境

1.只要短名称足够清楚,就要比长名称好

最后的话

1.取好名字最难的地方在于须要良好的描述技巧和共有文化背景

三.函数

短小,只作一件事

每一个函数一个抽象层级

1.要确保函数只作一件事,函数中的语句都要在同一抽象层级上

2.自顶向下读代码:向下规则,让代码拥有自顶向下的阅读顺序,让每一个函数后面都跟着下一抽象层级的函数,这样一来,在看函数列表时,就能循抽象层级向下阅读了,我把这叫作向下规则

switch语句

1.尽可能隐藏switch,不要暴露

使用描述性的名称

1.沃德原则:“若是每一个例程都让你感到深合已意,那就是整洁代码”

2.函数越短小,功能越集中,就越便于取个好名字

3.别惧怕长名称,长而具备描述性的名称,要比短而使人费解的名称好

4.命名方式要保持一致。使用与模块名一脉相承的短语、名词和动词给函数命名

函数参数

1.最理想的参数数量是零,有足够的理由才能用三个以上参数

2.事件:在这种形式中,有输入参数而无输出参数,程序将函数看做一个事件,使用该参数修改系统状态

3.对于转换,使用输出参数而非返回值使人迷惑,若是函数要对输入参数进行转换操做,转换结果就该体现为返回值

4.向函数传入布尔值会使方法签名马上变得复杂起来,大声宣布函数不止作一件事

5.若是函数看来须要两个、三个或三个以上参数,就说明其中一些参数应该封装为类了

6.有可变参数的函数多是一元、二元甚至三元,超过这个数量就可能要犯错了

7.对于一元函数,函数和参数应当造成一种很是良好的动词/名词对形式

无反作用

1.函数承诺只作一件事,但仍是会作其余被藏起来的事,会致使古怪的时序性耦合及顺序依赖

2.参数多数会被天然而然地看做是函数的输入

分隔指令与询问

1.函数要么作什么事,要么回答什么事,但两者不可得兼

使用异步替代返回错误码

1.从指令式函数返回错误码轻微违反了指令与询问分隔的规则。它鼓励了在if语句判断中把指令看成表达式使用

2.try/catch代码块把错误处理与正常流程混为一谈,最好把try和catch代码块的主体部分抽离出来,另外造成函数

3.错误处理就是一件事,处理错误的函数不应作其余事

4.依赖磁铁(dependency magnet):其余许多类都得导入和使用它,如一些错误码枚举类

别重复本身

结构化编程

1.函数中的每一个代码块都应该只有一个入口和一个出口

2.尽可能少使用break,continue,不能用goto

如何写出这样的函数

1.打磨代码,分解函数、修更名称、消除重复

2.缩短和从新安置方法、拆散类、保持测试经过

四.注释

1.若编程语言足够有表达力,就不须要注释

2.注释的恰当用法是弥补咱们在用代码表达意图时遭遇的失败。注释老是一种失败

3.程序员应当负责将注释保持在可维护、有关联、精确的高度,更应该把力气用在写清楚代码上,直接保证无须编写注释

4.不许确的注释要比没注释坏得多

注释不能美化糟糕的代码

用代码来阐述

五.格式

格式的目的

1.代码格式关乎沟通,而沟通是专业开发者的头等大事

垂直格式

1.经过间隔来区分逻辑模块

横向格式

1.适当对齐,间隔

团队规则

1.一组开发者应当认同一种模式风格,每一个成员都应该采用那种风格

2.好的软件系统是由一系列读起来不错的代码文件组成的,须要拥有一致和顺畅的风格

六.对象和数据结构

数据、对象的反对称性

1.过程式代码难以添加新的数据结构,由于这要修改全部相关函数;面向对象代码难以添加新函数,由于要修改全部相关类

得墨忒耳律

1.得墨忒耳律(The Law of Demeter):模块不该了解它所操做对象的内部情形,意味着对象不该经过存取器曝露其内部结构,由于这样更像是曝露而非隐藏其内部结构

2.混合结构,一半是对象,一半是数据结构,应避免这种结构

数据传送对象

1.最为精练的数据结构,是一个只有公共变量、没有函数的类,这种被称为数据传送对象,或DTO(Data Transfer Objects)。在与数据库通讯、或解析套接字传递的消息之类场景中存在。

2.JavaBean或Active Record

3.不要塞进业务规则方法,把Active Record当作数据结构。建立包含业务规则、隐藏内部数据(可能就是Active Record的实体)的独立对象。

七.错误信息

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

使用异常而非返回码

1.遇到错误时,最好抛出一个异常。调用代码很整洁,其逻辑不会被错误处理搞乱

先写Try-Catch-Finally语句

1.异常的妙处之一是,它们在程序中定义了一个范围。执行try-catch-finally语句中try部分的代码时,你是在代表可随时取消执行,并在catch语句中接续

2.在某种意义上,try代码块就像是事务,catch代码块将程序维持在一种持续状态

3.在编写可能抛出异常的代码时,最好先写try-catch-finally语句,能帮你定义代码的用户应该期待什么,不管try代码块中执行的代码出什么错都同样

使用不可控异常

1.可控异常,就是指在方法签名中标注异常。但有时候会产生多层波及,有时候你对较底层的代码修改,可能会波及不少上层代码

给出异常发生的环境说明

1.抛出的每一个异常,都应当提供足够的环境说明,以便判断错误的来源和处所

2.应建立信息充分的错误消息,并和异常一块儿传递出去

依调用者须要定义异常类

1.自定义的异常类最重要的考虑是它们如何被捕获

2.将第三方API打包是个良好的实践手段,下降了对每一个第三方的依赖,也有助于模拟第三方调用,并将一些复杂的异常捕获过程封装

定义常规流程

1.特例模式(SPECIAL CASE PATTERN,[Fowler]),建立一个类或配置一个对象,用来处理特例,异常行为被封装到特例对象中

尽可能别返回null值,也别传递null值

八.边界

使用第三方代码

1.第三方程序包和框架提供者追求普适性,这样就能在多个环境中工做,吸引普遍的用户

2.咱们建议不要将Map(或在边界上的其余接口)在系统中传递,把它保留在类或近亲类中,避免从API中返回边界接口,或将接口做为参数传递给公共API

学习性测试的好处不仅是免费

1.学习性测试毫无成本,编写测试是得到这些知识(要使用的API)的容易而不会影响其余工做的途径

2.学习性测试确保第三方程序包按照咱们想要的方式工做

使用尚不存在的代码

编写咱们想获得的接口,好处之一是它在咱们控制之下,有助于保持客户代码更可读,且集中于它该完成的工做

整洁的边界

1.边界上的改动,有良好的软件设计,无需巨大投入和重写便可进行修改

2.边界上的代码须要清晰的分割和定义了指望的测试。依靠你能控制的东西,好过依靠你控制不了的东西,省得往后受它控制

3.可使用ADAPTER模式将咱们的接口转换为第三方提供的接口

九.单元测试

TDD三定律

1.在编写能经过的单元测试前,不可编写生产代码(测试先行)

2.只可编写恰好没法经过的单元测试,不能编译也算不经过(测试一旦失败,开始写生产代码)

3.只可编写恰好足以经过当前失败测试的生产代码(老测试一旦经过,返回写新测试)

测试先行的一大好处:

若是先写测试,必然得知道输入是什么,指望输出的是什么。这样就不断促进思考该如何获得这样的输出,即把设计代码也放入了测试前期的准备中。

保持测试整洁

1.脏测试等同于没测试,测试必须随生产代码的演进而修改,测试越脏,就越难修改

2.测试代码和生产代码同样重要,它须要被思考、被设计和被照料,它该像生产代码通常保持整洁

3.若是测试不能保持整洁,你就会失去它们,没有了测试,你就会失去保证生产代码可扩展的一切要素

整洁的测试

1.三个要素:可读性、可读性和可读性,明确、简洁还有足够的表达力

2.构造-操做-检验(BUILD-OPERATE-CHECK)模式,第一个环节构造测试数据,第二个环节操做测试数据,第三个部分检验操做是否获得指望的结果

3.守规矩的开发者也将他们的测试代码重构为更简洁和具备表达力的形式

每一个测试一个断言

1.JUnit中每一个测试函数都应该有且只有一个断言语句

2.最好的说法是单个测试中的断言数量应该最小化

3.更好一些的规则或许是每一个测试函数中只测试一个概念

4.最佳规则是应该尽量减小每一个概念的断言数量,每一个测试函数只测试一个概念

F.I.R.S.T

1.快速(Fast)测试应该够快

2.独立(Independent)测试应该相互独立

3.可重复(Repeatable)测试应当可在任何环境中重复经过

4.自足验证(Self-Validating)测试应该有布尔值输出,本身就能给出对错,而不须要经过看日志,比对结果等方式验证

5.及时(Timely)测试应及时编写

十.类

类的组织

1.类应该从一级变量列表开始,若是有公共静态变量,应该先出现,而后是私有静态变量,以及实体变量,不多会有公共变量

2.公共函数应该跟在变量列表以后

3.保持变量和工具函数的私有性,但并不执着于此

类应该短小

1.职责单一,类的名称应当描述其权责,若是没法为某个类命以精确的名称,这个类大概就太长了,类名越含混,该类越有可能拥有过多权责;类或模块应有且只有一条加以修改的理由

2.内聚性强,方法操做的变量越多,就越黏聚到类上,若是一个类的每一个变量都被每一个方法所使用,则该类具备最大的内聚性

3.保持函数和参数列表短小的策略,有时会致使为一组子集方法所用的实体变量数量增长。出现这种状况时,每每意味着至少有一个类要从大类中挣扎出来。你应当尝试将这些变量和方法分拆到两个或多个类中,让新的类更为内聚

4.将大函数拆为许多小函数,每每也是将类拆分为多个小类的时机

为了修改而组织

1.在整洁的系统中,咱们对类加以组织,以下降修改的风险

2.开放-闭合原则(OCP):类应当对扩展开放,对修改封闭

3.在理想系统中,咱们经过扩展系统而非修改现有代码来添加新特性

4.依赖倒置原则(Dependency Inversion Principle,DIP),类应该依赖于抽象而不是依赖于具体细节

十一.系统

如何建造一个城市

1.每一个城市都有一组人管理不一样的部分,有人负责全局,其余人负责细节

2.深化出恰当的抽象等级和模块,好让我的和他们所管理的“组件”即使在不了解全局时也能有效地运转

将系统的构造与使用分开

1.构造与使用是很是不同的过程

2.软件系统应将启始过程和启始过程以后的运行时逻辑分离开,在启始过程当中构建应用对象,也会存在互相缠结的依赖关系

3.将构造与使用分开的方法之一是将所有构造过程搬迁到main或被称为main的模块中,设计系统的其他部分时,假设全部对象都已正确构造和设置

4.可使用抽象工厂模式让应用自行控制什么时候建立对象,但构造的细节却隔离于应用程序代码以外

5.控制反转将第二权责从对象中拿出来,转移到另外一个专一于此的对象中,从而遵循了单一权责原则。在依赖管理情景中,对象不该负责实体化对自身的依赖,反之,它应当将这份权责移交给其余“有权力”的机制,从而实现控制的反转

扩容

1.“一开始就作对系统”纯属神话,反之,咱们应该只去实现今天的用户故事,而后重构,明天再扩展系统、实现新的用户故事,这就是迭代和增量敏捷的精髓所在。测试驱动开发、重构以及它们打造出的整洁代码,在代码层面保证了这个过程的实现

2.软件系统与物理系统能够类比。它们的架构均可以递增式的增加,只要咱们持续将关注面恰当地切分

3.持久化之类关注面倾向于横贯某个领域的自然对象边界

Java代理

纯Java AOP框架

AspectJ的方面

测试驱动系统架构

1.经过方面式(AOP)的手段切分关注面的威力不可低估。假使你能用POJO编写应用程序的领域逻辑,在代码层面与架构关注面分离开,就有可能真正地用测试来驱动架构

2.不必先作大设计(Big Design Up Front,BDUF),BDUF甚至是有害的,它阻碍改进,由于心理上会抵制丢弃即成之事,也由于架构上的方案选择影响到后续的设计思路

3.咱们能够从“简单天然”但切分良好的架构开始作软件项目,快速交付可工做的用户故事,随着规模的增加添加更多基础架构

4.最佳的系统架构由模块化的关注面领域组成,每一个关注面均用纯Java(或其余语言)对象实现,不一样的领域之间用最不具备侵害性的方面或类方面工具整合起来,这种架构能测试驱动,就像代码同样

优化决策

1.模块化和关注面切分,成就了分散化管理和决策

2.延迟决策至最后一刻也是好手段,它让咱们可以基于最有可能的信息作出选择

3.拥有模块化关注面的POJO系统提供的敏捷能力,容许咱们基于最新的知识作出优化的、时机恰好的决策,决策的复杂性也下降了

明智使用添加了可论证价值的标准

1.有了标准,就更易复用想法和组件、雇用拥有相关经验的人才、封装好点子,以及将组件链接起来。不过,创立标准的过程有时却漫长到行业等不及的程度,有些标准没能与它要服务的采用者的真实需求相结合

系统须要领域特定语言

1.领域特定语言(Domain-Specific Language, DSL)是一种单独的小型脚本语言或以标准语言写就的API,领域专家能够用它编写读像是组织严谨的散文通常的代码

2.领域特定语言容许全部抽象层级和应用程序中的全部领域,从高级策略到底层细节,使用POJO来表达

十二.迭代

经过迭进设计达到整洁目的

简单规则:

* 经过全部测试

* 不可重复

* 表达了程序员的意图

* 尽量减小类和方法的数量

* 以上规则按其重要程序排列

简单设计原则2~4:重构

1.有了测试,就能保持代码和类的整洁,方法就是递增式地重构代码

2.测试消除了对清理代码就会破坏代码的恐惧

不可重复

表达力

尽量少的类和方法

十三.并发编程

为何要并发

1.并发是一种解耦策略,它帮助咱们把作什么(目的)和什么时候(时机)作分解开

2.解耦目的与时机能明显地改进应用程序的吞吐量和结构

3.单线程程序许多时间花在等待web套接字I/O结束上面,经过采用同时访问多个站点的多线程算法,就能改进性能

常见的迷思和误解

* 并发总能改进性能:只在多个线程或处理器之间能分享大量等待时间的时候管用

* 编写并发程序无需修改设计:可能与单线程系统的设计极不相同

* 在采用web或ejb容器时,理解并发问题并不重要

有关编写并发软件的中肯的说法

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

* 正确的并发是复杂的,即便对于简单的问题也是如此

* 并发缺陷并不是总能重现,因此常被看作偶发事件而忽略,未被当作真的缺陷看待

* 并发经常须要对设计策略的根本性修改

并发防护原则

1.单一权责原则

2.限制数据做用域

3.使用数据副本

4.线程应尽量独立

了解Java库

* 使用类库提供的线程安全群集

* 使用executor框架(executor framework)执行无关任务

* 尽量使用非锁定解决方案

* 有几个类并非线程安全的

了解执行模型

警戒同步方法之间的依赖

保持同步区域微小

很维编写正确的关闭代码

1.平静关闭很难作到,常见问题与死锁有关,线程一直等待永远不会到来的信号

2.建议:尽早考虑关闭问题,尽早令其工做正常

测试线程代码

1.建议:编写有潜力曝露问题的测试,在不一样的编程配置、系统配置和负载条件下频繁运行。若是测试失败,跟踪错误。别由于后来测试经过了后来的运行就忽略失败

2.将伪失败看做可能的线程问题:线程代码致使“不可能失败的”失败,不要将系统错误归咎于偶发事件

3.先使非线程代码可工做:不要同时追踪非线程缺陷和线程缺陷,确保代码在线程以外可工做

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

5.编写可调整的线程代码:容许线程依据吞吐量和系统使用率自我调整

6.运行多于处理器数量的线程:任务交换越频繁,越有可能找到错过临界区域致使死锁的代码

7.在不一样平台上运行:尽早并常常地在全部目标平台上运行线程代码

8.装置试错代码:增长对Object.wait()、Object.sleep()、Object.yield()、Object.priority()等方法的调用,改变代码执行顺序,硬编码或自动化

十四.逐步改进

1.要编写清洁代码,必须先写肮脏代码,而后再清理它

2.毁坏程序的最好方法之一就是以改进之名大动其结构

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息