【执行说明】
1、坦言之,编码规范是执行层面的规则,并不是贯穿项目过程始终的一条刚性原则,在执行的过程中,务必要实事求是、最求实际效果,千万不要教条的执行,僵化的执行。我在ThroughoutCMS的为期三年的产品管理过程中,对于编码规范的要求非常的高,可是说,在十多万行代码,我至少重头到尾的仔细review过不下10次,每次看到不规范的代码编写,就问自己:“为什么我规定的编码规范不被完整的执行?为什么不规范的代码没有影响产品的交付?”。说实话,我很自豪我们的产品从头到尾,几次的重构,关于交付质量,我还是引以为豪的,包括客户和同行的朋友,对我们的产品、对我们的团队,绝大部分都是赞扬有加。
2、团队中的人。当初的涉及到代码的几个人中,有四位核心人员:(1)李志罡是专攻元数据管理的骨干人员,他对我的规范性编码非常赞同,并提出了很多自己的意见;(2)雷奇文是一个初入社会的研究生,所谓一张白纸好画画,也执行的比较到位,我们的用户控制系统非常完美;(3)董少磊是一个个性鲜明的技术型人才,专攻内容管理,包括item管理和分类管理,很多很好的创意,已经成为行业精英的他现在再约束他已经很难,幸亏他也是刚入社会的研究生,比较听话,所以我们的内容管理核心模块也是很规范的。(4)第四位就是我,作为产品经理,同时也负责静态发布引擎核心模块的开发。自己的规范自己坚持,理所当然。
3、编码规范是开发规范中的一个子集,行业内有很多这方面现成的理论和概念,我最痛恨理论和概念,但是最后向同行专家进行交流和上级领导汇报的时候,总部不能说编码的土得掉渣哦的话,所以也适当的找了一些理论和概念模型作为我的依据,并且格式上也要遵循行业内的9000流程或者cmmi的规范,坦白说,就是装点门面、吹吹牛逼而已。在具体的工作中,根本不屑一顾。
4、coding有很多,比如常规的主程序代码、数据库脚本、前端js+css+html的编码、测试用例的脚本等等,能够规范的都规范,不能规范的尽量规范。
5、后来我担任软件部门经理的时候,要同时负责多个项目,包括中石化项目,采用java的;时代集团的crm,采用c#编写;几个PDM的项目,采用vb编写;还有和电子城的视频会议的项目,又采用c++编写。这时候,我感觉我的编码规范已经教条了,需要把里面的规范性统一性标准型作为核心思想抽取出来,作为原则性要求,让各个项目经理在这几个原则性要求的框架之下,再根据项目的实际需要,自己配置一份专门针对各自项目的编码规范去执行,事实证明,这种办法防止了左倾主义教条的错误发生,更多的体现了实事求是的原则。也获得了较好的效果。
6、来了盛大之后,我脱离的一线的开发,我发现对于软件管理,应该隶属于整个公司管理体系之下的一个小体系管理,所以不能一味的说我们的软件管理有问题,应该客观的去看,辩证的去理解,也就释然了。
【正文】 ---
第一章、 总则
一、开发技术规范的意义
为了保证企业编写出的程序都符合相同的规范,保证一致性、统一性而建立的程序编码规范。
编码规范对于程序员而言尤为重要,有以下几个原因:
(1)、一个软件的生命周期中,80%的花费在于维护;
(2)、几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护;
(3)、编码规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的代码;
(4)、如果你将源码作为产品发布,就需要确任它是否被很好的打包并且清晰无误,一如你已构建的其它任何产品;
为了执行规范,每个软件开发人员及其相关人员必须一致遵守编码规范。
适用于企业所有基于DNET体系和JAVA体系的软件开发工作。
二、文档的内容范围及其读者
本文档从以下方面对软件开发的规范进行了提纲挈领的阐述,当然,开发的规范虽然存在着普遍性,但是重点针对的是当前软件开发领域中的较为流行的B/S架构下的DNET/JAVA开发,以及目前公司二次开发中的基于C/S的二次开发(PLM)。
l 注释规范(文件注释、类注释等);
l 项目开发文件目录结构规范;
l 代码命名规范(包括类结构和命名空间);
l 代码格式(排版:换行、空格、缩进、括号等)规范;
l 程序流程规范;
l Html规范;
l Javascript规范;
l 资源(图片/flash等)文件规范;
l 数据库设计规范;
l 缩写规范;
本文档面对的读者主要是以下人员:
l 项目经理及其助理
项目启动之后,项目组成员到位之前,项目经理应该完成本文档的制订,并且生成各个规范的条目列表。
l 编码人员及其分析人员
项目开发人员人手一份次文档和相关的规范条目列表,严格按照以上的规范内容进行编码工作,分析人员进行系统分析的同时,应该兼顾本规范的内容,尽量避免设计方面出现于此规范冲突的情况。
l 质量控制人员
质量控制人员有义务在系统功能测试的过程中进行代码审查,确保此规范执行的情况,同时,应该对规范在执行过程中的问题进行相应的记录,并且提交给项目经理,对规范进行适应性的修改和完善。
三、参考的标准和文献
《C# CodingStandard Guidelines and Best Practices》version 1.81 ,Juval Lowy,www.Idesign.net
四、术语
(1)、 Pascal和Camel
编程的命名方式主要有Pascal和Camel两种(Pascal:每个单词的首字母大写,例如ProductType;Camel:首个单词的首字母小写,其余单词的首字母大写,例如productType)
(2)、 匈牙利命名规则
匈牙利命名规则是 Charles Simonyi 发明的一种给变量取名字的方式。他在变量前加上变量的类型,这样,看看变量的名字就知道变量的类型了。显然,这样做的缺点是要在名字前做这个记号。
五、版本信息
版本 |
时间 |
操作人 |
说明 |
1.0 |
2008年6月10日 |
贾俊奎 |
编码规范基本框架完成,注释规范要求初稿完成 |
第一章、 最佳实践
一、制定原则
(1)、形式反映内容
在一般情况下,我们都不要使用缩写命名,我们从来不害怕长的变量命名,而却担心看不懂的命名。
变量命名的原则是,尽最大努力让其他人在看到我们的变量/函数/…等的第一时间,大概能猜出它是做什么的。
比如:int productTypeCount = 0; //在第一时间就能知道它是记录产品的数量的变量
而对于糟糕的命名方式:int pTC = 0; //它是productTypeCount的简写,但是其他人或者我们在长时间以后还能知道它是做什么的吗?也许我们不得不查阅相关文档或跟踪代码前后文以明白其意义。
* 我们应该认为:最优秀的代码它本身就是注释。我们需要做的,并不在于当时潦草的去实现些什么,而是要让我们的代码具备让他人维护或今后扩充的能力。人需要美,代码也一样。
(2)、 统一即为规范
建议是使用默认控件名作为前缀,并且首字母小写,符合Camel规范,这样的好处是不必为未知的控件统一命名方式发愁,比如对于Label标签控件,有的人用缩写lbl,有的人用lab,有的人用lb……
protected System.Web.UI.WebControls.ButtonbuttonQuery;
protected System.Web.UI.WebControls.DropDownListdropDownListProductType;
protected System.Web.UI.WebControls.TextBoxtextBoxManufactureDate;
总之,代码编写只要统一,可溯性好,就是好代码。开发规范制订的根本目的之一,也就是保证代码的统一和可溯性。
(3)、 适用即为优秀
开发规范本身就是一种约定,其约束访问应该定义在特定项目开发的过程之中,本身不是僵化的、也不是死板教条的,更不是放之四海皆准的。对于某一个项目的过程较为良好的开发规范可能对于另外的项目(源于开发的平台、语言、规模、性质、开发的方式等差异)的过程,就不是良好的。不能盲目的照搬、教条的使用。
项目开发规范的执行应该统筹考虑,依此文档作为基础,进行内容的剪裁、配置,重新定义生成一个适用于本项目的《***项目软件开发规范》。
(4)、 成长的规范
本规范不是一成不变的,而是可以发展的,任何项目的开发人员都可以在实际的工作过程中,针对此规范的内容提出建设性的意见,当然,在新规范没有推出之前,之前的规范必须无条件严格执行。
二、项目实施原则
(1)、 规范的制订
项目启动过程中,项目经理在组建开发队伍之前,根据项目的实际情况,遵循根据本文档的主题思想,选择适用的规范内容,制订适合于项目开发的《开发规范》和《标准规范参照表》。
(2)、 规范的培训
先对设计人员和编码人员进行“专题”培训,让他们掌握此编码规则。并且分发给每个相关人员。
其次,对于测试人员和质量控制人员进行培训,并且以此作为其工作内容的组成部分。
(3)、 规范的实施
设计人员必须兼顾编码规范,不能冲突。
编码人员按照此规范进行编码。
代码审查和走查人员根据此规范进行审查。
测试人员依此规范作为依据,对代码进行内部的测试。
系统设计人员、编码人员、测试人员可以提出较好的建议,适当地修改完善;
(4)、 规范的成长
对本文档修改要做出记录,变更版本号。
第二章、 注释规范
一、注释基本原则
(1)、尽量使用 XML 文档格式
如下面方法的注释:
/// <summary>
/// 得到某人的年龄
/// </summary>
/// <param name="userName">用户名</param>
/// <returns>用户年龄</returns>
public int GetUserAge(string userName)
{
//
//此处写你的程序代码
//
}
(2)、注释保持同步
修改代码时,总是使代码周围的注释保持最新。
(3)、禁止增加印刷框
避免在块注释的周围加上印刷框。这样看起来可能很漂亮,但是难于维护。
(4)、禁止出现无注释对象
对于类、成员变量、函数、代理、结构体、常量等重要语句,禁止出现没有注释的情况。
二、核心文件头部注释;
【位置】:
在程序文件的最上端(顶部)
【内容】:
必选项:程序文件名称、文件摘要、版本信息(保留最新5条,其他归档)
可选项:项目信息、单位信息
【范例】:
//============================================================================
// 中国地质调查局网站内容发布系统 ASP.NET
// http://www.throughout.com.cn
//
// ApplicationToSaTicket.cs
//
// 本文件包含了ApplicationToSaTicket通用函数.
//
// 更多的信息请参考项目的有关文档.
//=============================================================================
//Release history
// 版本 时间 修改人员 描述信息
// 1.0 2005-12-12 贾俊奎 创建成功
//============================================================================
// Copyright (C) 2005-2006 北京思奥特科技发展有限公司 All rights reserved.
//===========================================================================
其中黑色部分为必选项,也是检查项;
三、类注释
(1)、 类注释
【位置】:类定义之上
【内容】:
必选项:类名称、类摘要(侧重用途)
可选项:无
【格式】:
///<summary>
/// 类的说明
///</summary>
【范例】:
///<summary>
///ApplicationToSaTicket,是一种应用服务器向认证服务器发送的ticket,不写入到/// 用户的cookie,是应用服务器对客户进行第一步验证之后
/// 没有通过,然后直接推向SA服务器,在SA服务器端进行第二步的验证
///</summary>
(2)、 成员变量注释
【位置】:成员变量定义之上
【内容】:
必选项:变量摘要(侧重用途)
可选项:无
【格式】:
///<summary>
/// 变量的说明
///</summary>
【范例】:
///<summary>
///本次认证请求的一个返回的URL
///</summary>
privatestring m_RedirectURL="";
【其他】:
类型,访问控制等修饰符号不必注释说明
(3)、 成员属性注释
【位置】:成员属性定义之上
【内容】:
必选项:属性的意义和类型
可选项:创建的时间和创建者可以在summary中说明。
【格式】:
///<summary>
/// 属性说明;读写方式。
///</summary>
【范例】:
///<summary>
///属性:RedirectURL;读写
///</summary>
publicstring RedirectURL
{
set{this.M_RedirectURL= value;}
get{returnthis.M_RedirectURL;}
}
【其他】:
尽量保持类文件的编写修改人员的唯一性。
(4)、成员函数注释
【位置】:成员函数定义之上
【内容】:
必选项:函数的应用目的、参数说明、返回值说明
可选项:函数创建的时间和创建者可以在summary中说明。
【格式】:
/// <summary>
///说明:该方法的说明
/// </summary>
/// <param name="参数名称">参数说明</param>
/// <returns>返回值的说明,返回值的意义 </returns>
【范例】:
///<summary>
/// 删除应用
///</summary>
///<param name="mid">应用的APP_SID</param>
///<returns>true;操作成功;false,操作失败</returns>
publicstatic bool DeleteApp(int mid)
【其他】:
尽量保持类文件的编写修改人员的唯一性。
四、修改注释
【位置】:
当开发者或者质量控制人员维护以前的程序代码时,需要在修改处的开始及结尾,加上自己的注释信息,
【内容】:
必选项:修改时间、修改人员、修改内容(侧重用途)
可选项:无
【范例】:
//BEGIN 2004-7-19 Jayson 修正了XXX问题
略…
//END 2004-7-19 Jayson
【其他】:
同一段代码仅仅保留最后一次的修改注释内容,并且最后进行代码提交测试完毕之后删除修改注释。
同时,在文件的头部保留版本信息;
五、代码间注释
在逻辑性较强的地方加入注释,说明这段程序的算法逻辑流程,以方便后来的理解以及其他人的理解,并且这样还可以在一定程度上排除BUG。在注释中写明我们的逻辑思想,对照程序,判断程序是否符合设计的初衷。
以下情况下需要代码间的注释:
n 临时变量
n 关键的算法
n 价位难理解的语句
n 多层嵌套循环或者条件语句
代码间注释分为单行注释和多行注释:
(1)、单行注释:
//<单行注释>
(2)、多行注释:
/*多行注释1
多行注释2
多行注释3*/
代码中遇到语句块时必须添加注释(if,for,foreach,……),添加的注释必须能够说明此语句块的作用和实现手段(所用算法等等)。
注意:
(1)、注释必须使用汉字。
(2)、同步即时性。写代码同时完成注释,修改代码同时修改相应的注释,以保证注释与代码的一致性;
(3)、就近原则。在必要的地方注释,注释量要适中。注释的内容要清楚、明了,含义准确,防止注释二义性。保持注释与其描述的代码相邻,即注释的就近原则;
第三章、 项目开发文件目录结构规范
一、基本原则
项目在实际运行过程中,存在以下类型的文件目录:
(1)、通用函数库或者空间库
例如:自行编写的通用的函数库。
推荐:位于根目录下,只能存在一个,内部目录划分自行定义;
(2)、控件库
例如:第三方控件或部门控件。
推荐:位于根目录下,一个或多个,内部目录划分自行定义;
(3)、程序功能文件
例如:按照程序逻辑功能划分目录结构
(4)、资源文件库
例如:图片、脚本、css、flash、vidio等资源引用文件。
推荐:位于根目录下,只能存在一个,内部目录划分自行定义;
(5)、数据交换库
例如:CMS的非结构文件库DataRepository,静态页输出库htmldocs等;
推荐:目录位置根据实际情况而定,一个或多个,内部目录划分自行定义;
二、文件命名基本原则
文件命名反映文件的意义
推荐方式:主+谓+宾结构方式,主动者对客体对象,发生了什么操作
举例:
项目 |
内容 |
类型 |
aspx网页 |
作用 |
为会员提供注册服务页面 |
不符规范的例子 |
WebForm1.aspx、NewMember.aspx |
规范的例子 |
Member_Create.aspx |
说明 |
|
注意:当主语和宾语相同的时候,可以省略宾语
三、文件目录规范
文件目录规范,推荐使用上述原则,但不作刚性要求。
项目开发的文件要求如下:
概要设计之后,提交目录结构清单vss“***项目”目录下“04、产品实现”目录中,列出层次结构和名称,并且对目录进行必要描述。
产品实现之后,提交程序文件清单到vss“***项目”目录下“04、产品实现”目录中,列出文件对应的目录,以及文件名陈,并且进行必要描述。