java编码规范培训.ppt

上传人:本田雅阁 文档编号:2145546 上传时间:2019-02-21 格式:PPT 页数:43 大小:462.01KB
返回 下载 相关 举报
java编码规范培训.ppt_第1页
第1页 / 共43页
java编码规范培训.ppt_第2页
第2页 / 共43页
java编码规范培训.ppt_第3页
第3页 / 共43页
亲,该文档总共43页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《java编码规范培训.ppt》由会员分享,可在线阅读,更多相关《java编码规范培训.ppt(43页珍藏版)》请在三一文库上搜索。

1、Java编码规范 培训教材,2009年1月14日,简介,本文提供一整套编写高效可靠的 Java 代码的标准、约定和指南。它们以安全可靠的软件工程原则为基础,使代码易于理解、维护和增强。而且,通过遵循这些程序设计标准,作为一个 Java 软件开发者的生产效率会有显著提高。经验证明,若从一开始就花时间编写高质量的代码,则在软件开发阶段,对代码的修改要容易很多。最后,遵循一套通用的程序设计标准将带来更大的一致性,使软件开发团队的效率明显提高。,最根本的原则,运用常识。当找不到任何规则或指导方针,当规则明显不能适用,当所有的方法都失效的时侯: 运用常识并核实这些基本原则。这条规则比其它所有规则都重要。

2、常识是必不可少的。 参考SUN java SDK中的代码,这些代码、注释是比较标准的。,程序设计标准,Java 的程序设计标准很重要,原因在于它将提高开发团队各成员的代码的一致性。一致性的提高会使代码更易理解,这意味着它更易开发和维护。从而降低了应用程序的总开发成本。 你必须牢记的是:你的 Java 代码在你已离开并开始另一个项目之后,会保留相当长的一端时间。因此开发过程中一个很重要的目标就是要确保在开发成员或开发团队之间的工作可以顺利交接,不必花很大的力气便能理解已编写的代码,以便继续维护和改进以前的工作。如果代码难以理解,很有可能被废弃和重写。,命名约定,我们将在整个标准中讨论命名约定,所

3、以让我们先讨论几个基本点,命名约定-使用可以准确说明变量/字段/类的完整的英文描述符,例如,采用类似 firstName,grandTotal 或 CorporateCustomer 这样的名字。虽然象 x1,y1 或 fn 这样的名字很简短,输入起来容易,但是我们难以知道它们代表什么、结果是什么含义,因而使代码难以理解、维护和改进。,命名约定-采用该领域的术语,如果用户称他们的“客户” (clients) 为“顾客” (customers),那么就采用术语 Customer 来命名这个类,而不用 Client。许多程序开发者会犯的一个错误是,不去使用工业或领域里已经存在着很完美的术语时,却生

4、造出一些普通词汇。,命名约定-采用大小写混合,提高名字的可读性,一般应该采用小写字母,但是类和接口的名字的首字母,以及任何中间单词的首字母应该大写,命名约定-尽量少用缩写,但如果一定要使用,就要谨慎地使用,这意味着应该保留一个标准缩写的列表,明智地从中选取,并且在使用时保持一致。例如,想对单词“number”采用缩写,那么可从 nbr,no 或者 num 中选取一个,说明一下采用了哪一个(具体是哪个倒无所谓),并且只使用这一种形式。,命名约定-避免使用长名字,虽然 PhysicalOrVirtualProductOrService 看起来似乎是个不错的类名,但是这个名字太长了,应该考虑重新给它

5、起个短一点的名字,比如象 Offering。,命名约定-避免使用相似或者仅在大小写上有区别的名字,例如,不应同时使用变量名 persistentObject 和 persistentObjects,以及 anSqlDatabase 和 anSQLDatabase。,注释约定,注释应该增加代码的清晰度 避免使用装饰性内容,也就是说,不要使用象广告横幅那样的注释语句 保持注释的简洁 先写注释,后写代码 注释信息不仅要包括代码的功能,还应给出原因,成员函数标准,命名成员函数 成员函数的命名应采用完整的英文描述符,大小写混合使用:所有中间单词的第一个字母大写。成员函数名称的第一个单词常常采用一个有强烈

6、动作色彩的动词。 示例: openAccount() printMailingLabel() save() delete() 这种约定常常使人一看到成员函数的名称就能判断它的功能。虽然这种约定要使开发者多做一些输入的工作,因为函数名常常较长,但是回报是提高代码的可理解性。,命名存取成员函数,获取函数 获取函数作为一个成员函数,返回一个字段的值。除了布尔字段之外,应采用 get 作为字段的前缀;布尔字段采用 is 作为前缀。 示例: getFirstName() getAccountNumber() isPersistent() isAtEnd() 遵循这个命名约定,显然,成员函数将返回对象的字

7、段,布尔型的获取函数将返回布尔值“真”或者“假”。这个标准的另一个优点是:它遵循 beans development kit (BDK) 对获取成员函数采用的命名约定 DES97。它的一个主要的缺点是 get 是多余的,需要额外的录入工作。,设置函数,设置函数,也叫变值函数,是可以修改一个字段值的成员函数,。无论何种字段类型,都要在字段名的前面加上 set 前缀。 示例: setFirstName(String aName) setAccountNumber(int anAccountNumber) setReasonableGoals(Vector newGoals) setPersiste

8、nt(boolean isPersistent) setAtEnd(boolean isAtEnd) 按照这种命名约定,显然是一个成员函数设定一个对象的字段值。这个标准的另一个优点是:它遵循 beans development kit (BDK) 对设置函数采用的命名约定 DES97。,命名构造函数,构造函数是在一个对象初次生成时,完成所有必需的初始化的成员函数。构造函数与它所属类的名字总是相同的。例如,类 Customer 的构造函数是 Customer()。注意大小写一致。 示例: Customer()SavingsAccount()PersistenceBroker() 这个命名约定由

9、Sun 公司设定,必须严格遵守。,成员函数的可见性,良好的程序设计应该尽可能减小类与类之间耦合,所遵循的经验法则是:尽量限制成员函数的可见性。如果成员函数没必要公有 (public),就定义为保护 (protected);没必要保护 (protected),就定义为私有 (private)。 可见性说明正确用法 public公有成员函数可被任何其它对象和类的成员函数调用。当该成员函数必须被该函数所在的层次结构之外的其他对象和类在访问时。 protected被保护的成员函数可被它所在的类或该类的子类的任何成员函数调用。当该成员函数提供的行为被它所在类的层次结构内部而非外部需要时。 private

10、私有成员函数只可以被该类所在的其它成员函数调用,该类的子类不可以调用。当该成员函数所提供的行为明确针对定义它的类时。私有成员函数常常是重新分配要素的结果。重新分配要素又叫“重组”,指类内其它成员函数封装某一个特定行为的做法。,注释成员函数,如何注释一个成员函数常常成为判断函数是否可被理解,进而可维护和可扩展的决定性因素。,成员函数的函数头,每一个 Java 成员函数都应包含某种称之为“成员函数文档”的函数头。这些函数头在源代码的前面,用来记录所有重要的有助于理解函数的信息。 这些信息包含但不仅仅局限于以下内容: 成员函数做什么以及它为什么做这个 哪些参数必须传递给一个成员函数 成员函数返回什么

11、 已知的问题。成员函数中的任何突出的问题都应说明,以便让其他程序开发者了解该成员函数的弱点和难点。如果在一个类的多个成员函数中都存在着同样的问题,那么这个问题应该写在类的说明里。,成员函数的函数头,任何由某个成员函数抛出的异常。应说明成员函数抛出的所有异常,以便使其他程序员明白他们的代码应该捕获些什么。在 (第 1.4.2节“快速浏览 javadoc”) 中讨论的 javadoc exception 标识便用于此目的。 可见性决策。如果你觉得你对于一个成员函数可见性的选择会遭到别人的质疑,例如可能你将一个成员函数设为公共的,但是却没有任何对象调用该成员函数,那么应说明你的决定。这将帮助其他开发

12、者了解你的想法,使他们不必浪费时间操心考虑你为什么要选择一种有疑问的东西。,成员函数的函数头,仅当注释增加代码的清晰度时,才应加上注释 对于每个成员函数,并非要说明以上所有部分,因为对于每一个成员函数来说,并不是以上所有的部分都适用。但是,对于所写的每个成员函数要说明以上的部分内容。,内部注释,除成员函数注释以外,在成员函数内部还需加上注释语句来说明你的工作。 目的是使成员函数更易理解、维护和增强。 内部注释应采用两种方式:C 语言风格的注释 (/* 和 */) 和单行注释 (/)。正如上述所讨论的,应认真考虑给代码的业务逻辑采用一种风格的注释,给要注释掉的无用代码采用另外一种风格的注释。建议

13、对业务逻辑采用单行注释,因为它可用于整行注释和行末注释。采用 C 语言风格的注释语句去掉无用的代码,因为这样仅用一个语句就可以容易地去掉几行代码,内部注释,在函数内,一定要说明: 控制结构。说明每个控制结构,例如比较语句和循环。你无须读完整个控制结构内的代码才判断它的功能,而仅需看看紧靠它之前的一到两行注释即可。 代码做了些什么以及为什么这样做。通常你常能看懂一段代码做了什么,但对于那些不明显的代码,你很少能判断出它为什么要那样做。例如,看完一行代码,你很容易地就可以断定它是在定单总额上打了 5% 的折扣。这很容易。不容易的是为什么要打这个折扣。显然,肯定有一条商业法则说应打折扣,那么在代码中

14、至少应该提到那条商业法则,这样才能使其他开发者理解你的代码为什么会是这样。 局部变量。虽然我们在第 4 章将仔细讨论这一点,在一个成员函数内定义的每一个局部变量都应在它代码的所在行声明,并且应采用一个行内注释说明它的用法。 难或复杂的代码。若发现不能或者没有时间重写代码,那么应将成员函数中的复杂代码详细地注释出来。一般性的经验法则是,如果代码并非显而易见的,则应说明。 处理顺序。如果代码中有的语句必须在一个特定的顺序下执行,则应保证将这一点注释出来 AMB98。没有比下面更糟糕的事了:你对一段代码做一点简单的改动,却发现它不工作,于是花了几个小时查找问题,最后发现原来是搞错了代码的执行顺序。,

15、编写清晰整洁的代码的技巧,给代码加上注释 给代码分段 使用空白 遵循 30 秒条规则 说明消息发送的顺序 写短小单独的命令行,让代码分段/缩进,一种提高代码可读性的方法是给代码分段,换句话说,就是在代码块内让代码缩进。所有在括号 和 之内的代码,构成一个块。基本思想是,块内的代码都应统一地缩进去一个单位。 Java 的约定似乎是开括号放在块的所有者所在行的后面,闭括号应缩进一级。在 LAF97 指出的很重要的一点是,你所在的机构应选取一个缩进风格并始终使用这种风格。采用与你的 Java 开发环境所生成的代码一样的缩进风格。 在代码中使用空白。 在 Java 代码中加入几个空行,也叫空白,将代码

16、分为一些小的、容易理解的部分,可以使它更加可读。VIS96 建议采用一个空行来分隔代码的逻辑组,例如控制结构,采用两个空行来分隔成员函数定义。没有空白的代码很难读,很难理解。,遵循 30 秒条法则,其他的程序员应能在少于 30 秒钟的时间内完全理解你的成员函数,理解它做什么,为什么这样做,它是怎样做的。如果他们做不到,说明你的代码太难维护,应加以改进。30 秒钟,明明白白。 一个好的经验法则是:如果一个成员函数一个屏幕装不下,那么它就很可能太长了。,写短小单独的命令行,每一行代码只做一件事情。 若想在一行里做多件事情,就会使代码难于理解。为什么要这样呢?我们应使代码尽量容易理解,从而更容易维护

17、和改进。正如同一个成员函数应该并且只能做一件事一样,一行代码也只应做一件事情。 此外,应让代码在一个屏幕内可见 VIS96。 也不应向右滚动编辑窗口来读取一整行代码,包括含有行内注释语句的代码。,字段标准,field 这个词在这里指的是字段,Beans Development Kit (BDK) 叫它“属性” DES97。字段是说明一个对象或者一个类的一段数据。字段可以是象字符串或者浮点数这样的基本数据类型,也可以是一个对象,例如一个消费者或者一个银行帐户。 应采用完整的英文描述符来命名字段 GOS96,AMB98,以便使字段所表达的意思一目了然。象数组或者矢量这样是集合的字段,命名时应使用复

18、数来表示它们代表多值。 示例: firstName zipCode unitPrice discountRate orderItems,命名组件(部件),应采用完整的英文描述符命名组件(接口部件),名字的后缀是组件类型名。这让你容易区分一个组件的目的和它的类型,容易在一个表里找到各个组件(许多可视化的编程环境在一个 Applet 程序或者一个应用程序中提供了一个所有组件的列表。如果所有名字都是类似于 button1, button2, & 这样的话,很容易混淆)。 示例: okButton customerList fileMenu newFileMenuItem,命名常量,Java 中,常量

19、,即不变的值,一般用类的静态常量字段来实现。公认的约定是,采用完整的英文大写单词,在词与词之间用下划线连接 GOS96。 示例: MINIMUM_BALANCE MAX_VALUE DEFAULT_START_DATE 这个约定的主要优点是,它有助于区分常量和变量。在本文后面的章节中我们将看到,如果用定义获取函数返回常量值的方法来取代定义常量,代码的可适应性和可维护性都会大大提高。,命名集合,一个集合,例如数组和矢量,应采用复数命名来表示队列中存放的对象类型。命名应采用完整的英文描述符,名字中所有非开头的单词的第一个字母应大写。 示例: customersorderItemsaliases 这

20、种约定的主要优点是有助于区分表示复数值(集合)和单值(非集合)的字段。,不要“隐藏”名字,字隐藏是指给局部变量、参数或者字段所取的名字,与另一个更大范围内定义的变量、参数或者字段的名字相同(或相似)。例如,如果把一个字段叫做 firstName ,就不要再生成一个局部变量或者参数叫做 firstName,或者任何类似的名字,如 firstNames 或 fistName。名字隐藏会使代码难于理解,并容易产生问题。因为你或者其他开发者在修改代码时,会误读代码,而错误又很难发现。,注释一个字段,所有的字段都应很好地加以注释,以便其他开发者理解它。要想有效地注释,以下的部分需要说明: 字段的说明。需

21、说明一个字段,才能使人了解如何使用它。 注释出所有采用的不变量。字段中的不变量是指永远为“真”的条件。例如,字段 dayOfMonth 的不变量可能是它的值只能在 1 到 31 之间(显然,可以用基于某一年里的某个月份来限制这个字段值,使其变的更加复杂)。通过说明字段值的限制条件,有助于定义重要的业务规则,使代码更易理解。 示例。对于那些有复杂业务规则与之相关联的字段,应提供几个例子,使它们容易理解。一个例子常象一幅画:它抵得上几千个词语。 并行事件。对众多程序开发者来说,并行性是一个新而复杂的概念;事实上,即使对有经验的并行程序开发者来说,并行性也是一个老但却复杂的课题。最终结果是,如果应用

22、了 Java 的并行编程特性,那么你应在程序中详细地注释出来。,命名存取函数,获取成员函数应在名字中加上 get + 字段名,除非字段表示的是一个布尔值(“真”或者“假”),这时获取函数名中应加上 is + 字段名。无论何种字段类型,设置成员函数应在名字中加上 set + 字段名 GOS96,DES97。注意字段名始终采用大小写混合,所有单词的第一个字母要大写。命名约定在 JDK 中被始终使用,在 beans development 中也必须使用。 Examples: 字段类型 获取函数名 设置函数名 firstName 字符串 getFirstName() setFirstName() ad

23、dress 地址对象 getAddress() setAddress() persistent 布尔值 isPersistent() setPersistent() customerNo 整型 getCustomerNo() setCustomerNo() orderItems OrderItem的对象数组 getOrderItems(),类的声明,一种让你的类容易被理解的方法是用一致的方式来声明它们。Java 中常用的方法是按如下顺序声明一个类: 公共成员函数 公共字段 被保护成员函数 被保护字段 私有成员函数 私有字段,将公共和保护接口最小化,向对象程序设计的基本点之一是最小化一个类的公共

24、接口。这样做有几个理由: 可学习性。要了解如何使用一个类,只需了解它的公共接口即可。公共接口越小,类越容易学习。 减少耦合。当一个类的实例向另一个类的实例或者直接向这个类发送一条消息时,这两个类变得耦合起来。最小化公共接口意味着将耦合的可能降到最低。 更大的灵活性。这直接与耦合相联系。一旦想改变一个公共接口的成员函数的实现方法,如你可能想修改成员函数的返回值,那么你很可能不得不修改所有调用了该成员函数的代码。公共接口越小,封装性就越大,代码的灵活性也越大。 尽力使公共接口最小化这一点明显地很值得你的努力,但通常不明显的是也应使被保护接口最小化。基本思想是,从一个子类的角度来看,它所有超类的被保

25、护接口是公共的。任何在被保护接口内的成员函数可被一个子类调用。所以,出于与最小化公共接口同样的理由,应最小化类的被保护接口。,首先定义公共接口,大多数有经验的开发者在开始编写类的代码之前就先定义类的公共接口。 第一,如果你不知道一个类要完成怎样的服务/行为,你仍有一些设计工作要做。第二,这样做使这个类很快地初具雏形,以便其他有赖于该类的开发者在“真正的”类被开发出来以前至少可以用这个雏形开始工作。 第三,这种方法给你提供了一个初始框架,围绕着这个框架你构造类。,包的标准 -命名包,关于包的命名有几条规则。按顺序来说,这些规则是: 标识符用点号分隔开来。为了使包的名字更易读,Sun 公司建议包名

26、中的标识符用点号来分隔。例如,包名 java.awt 含有两个标识符 java 和 awt。 Sun 公司的标准 java 分配包用标识符 .java 开头。Sun 保有这种权利,使得无论你的 Java 开发环境的零售商是怎样的,标准 java 包的命名始终一致。 局部包的名字中的第一个标识符不能都是大写。所谓局部包是指那些在你的机构内部使用,不会应用到其他机构中去的包。这样的包的名字的例子有 persistence.mapping.relational 和interface.screens。 全局包的名字用你的机构的 Internet 保留域名开头。一个要应用到多个机构的包应包含创建机构的域

27、名,并且最高层的域名类型要大写。例如,要应用前面的包,它们应被命名为 com.rational.www.persistence.mapping.relational 和 com.rational.www.interface.screens。0,错误处理和异常,系统在正常状态下以及无重载和硬件失效状态下,不应产生异常。 尽早采用适当的日志机制来报告异常,包括在异常发生的时刻。 不得不在每一级处理大量的异常使得代码难于理解和维护。有时,异常阻碍了正常的处理。 对于经常发生的可预计事件不要采用异常。 不要使用异常实现控制结构 在代码进行安全性检查,不要指望你的客户会去做这件事,导入类,在说明类名时,

28、import 语句允许使用通配符。例如, import java.awt.* 语句 一次性地引入了包 java.awt 中的所有类。 实际上,这并不完全正确。实际情况是每一个所使用的取自于 java.awt 包中的类,在编译时被引入代码,而其中未使用的类不被引入。虽然这听起来象是一个好的特点,但是它却降低了代码的可读性。一个更好的方法是完全限制代码所使用的类的名字 LAF97,VIS96。一个较好的导入类的方法如下面的例子所示: import java.awt.Color; import java.awt.Button; import java.awt.Container;,有效地使用这些标准

29、,以下的建议将帮助你更有效地使用本文所描述的 Java 编程标准和指南: 理解标准。花些时间去理解为什么每个标准和指南会使开发效率提高。比如说,不要仅仅是因为指南中要求你才在一行仅声明一个局部变量,而应该是因为你明白它能使你的代码更易懂你才这样做。 信任这些标准。理解每个标准是一个开始,但你还需要信任这些标准。遵守标准不应仅仅是当你有时间才做的事,而你应该一直遵守,因为你相信这是最好的程序设计方法。 当你写代码时就应该遵守标准,而不应是一个事后的想法。加了注释的代码不仅在你写程序时,而且在你写完程序时,都更容易理解。在程序开发阶段和维护阶段,一致性地命名成员函数和字段都使工作更加容易。 在开发

30、和维护阶段,整洁的代码让工作更加容易。概括起来说,遵守标准将提高你开发过程中的生产率,并且使你的代码更易维护(因此也使维护者的生产率提高了)。如果从一开始你就写出整洁的代码,你将在撰写过程中受益。 使它们成为你的质量保证的过程。代码检查的一部分应该是确保源码遵守你的机构所采用的标准。将标准作为你训练和指导开发员更有效率的基础。,其它导向成功代码的因素,面向人而不是面向机器编程。你的开发努力的主要目的应该是你的代码易被其它人理解。如果没人能理解它,它就一点儿优点也没有。使用命名约定。注释代码。给代码分段。 首先设计,然后编写代码。 一小步一小步地开发。一小步一小步地开发,先写几个成员函数,检测它们,再多写几个,这样开发比一次性地写完所有代码然后修改它要有效得多。 让代码简洁。复杂的代码或许让人在智力上获得满足,但是如果别人读不懂, 那就不好了。如果要求某人,甚至是你,第一次修改一段复杂的代码以纠正其中的错误或对它进行增强,那么很可能代码会被重写。 学习常用的模式、反模式和代码模式。 有大量的分析、设计和处理的模式和反模式以及编程代码模式供你提高开发效率。,欢迎指正,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1