软件项目质量保证——编码规范
目录一 编码规范的作用二 编码规范不是“物神”三 编写编码规范的一些建议四 编码规范参考 作为软件开发者,我们可以开发低等级的软件,但不能开发低质量的软件。所以,如何实施质量保证,是我们关注的主要问题之一,而编码规范则是实施质量保证的第一步。 编码规范已经成为一个老生常谈的问题,几乎每个项目,每家公司都会定义自己的编码规范。但在真正实施时,却在有意或无意地违背编码规范。程序员,不喜欢改变自己的编程习惯。加之,管理者对质量控制不足,导致编码规范往往形同虚设。有些人会认为:遵守编码规范不能给项目带来利益,也不能让客户看到我们为此付出的努力,其完全是团队自发的行为,没有必要做硬性的要求。还有些人有更好的理由:编码规范会破坏创造性和程序质量。我认为,编码规范,在软件构件以及项目管理中,甚至是个人成长方面,都发挥着重要的作用,好的编码规范是提高我们代码质量的最有效的工具之一。一 编码规范的作用[*]提高可读性 “任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优先的程序员。”编码规范,帮助我们写出人类容易理解的代码,它为我们提供了最基本的模板,良好的编码风格,使代码具有一定的描述性,可以通过名字来获取一些需要IDE才能得到的提示,如可访问性、继承基类等。
[*]统一全局,促进团队协作 开发软件是一个团队活动,而不是个人的英雄主义。编码规范,要求团队成员遵守这一统一的全局决策,这样成员之间可以轻松地阅读对方的代码,所有成员正以一种清晰而一致的风格进行编码。而且,开发人员也可以集中精力关注他们真正应该关注的问题——自身代码的业务逻辑,与需求的契合度等局部问题。
[*]有助于知识传递,加快工作交接 风格的相似性,能让开发人员更迅速,更容易理解一些陌生的代码,更快速地理解别人的代码。因为,他和你的代码风格是一样的,你没有必要对他的一些个性化风格进行揣测。这样的好处是开发人员可以很快的接手项目组其他成员的工作,快速完成工作交接。
[*]减少名字增生,降低维护成本 在没有规范的情况下,和容易为同一类型的实例起不同的名字。对于以后维护这些代码程序员来说会产生疑惑。
[*]强调变量之间的关系,降低缺陷引人的机会 命名可以表示一定的逻辑关系,是开发人员在使用时保持警惕,从而一定程度上减少缺陷被引人的机会。
[*]提高程序员的个人能力 不可否认,每个程序员都应该养成良好的编码习惯,而编码规范无疑是教材之一。从一个程序员的代码本身能看出很多东西。所以,即便是为了自身发展,作为程序员也没有理由抵制这种规则的存在。你可能没有认识到,我们正默默地得益于编码规范。
二 编码规范不是“物神” 在高质量的软件中,你可以看到“架构的概念完整性”与“底层实现”之间的关系。“实现”与“架构”必须是清晰一致的,这种内在的、固有的一致性,需要编码规范来维系。如果没有这种统一的约定,那么我们做出的东西可能会充斥着各种不同的风格,显得混乱且难以理解。团队成员之间可能很不理解彼此之间的想法,甚至是相互抨击。各种编码风格上的差异会不断扩大,而代码质量则不断下降。而且,团队成员会花费时间在理解不同编程风格之间的差异,而没有专注于真正应该解决的问题。这样的时间消耗是难以接受的。所以,在每一个高质量代码的背后,一定存在着一份优秀的编码规范。 然而,也必须认识到编码规范不是“物神”。编码规范仅仅是一个全局性质的规范,它只不过是一种编程约定,不能解决更深层次的问题。就像一篇格式漂亮但内容糟糕的论文不能被发表一样,你不能仅靠一个规范来摆脱软件作坊。而且,在编码规范中不宜包含那些冗长的开发技巧。我认为,对于代码是最佳实践应该是代码审查所要解决的,应该避免将编码规范写成一部关于重构的教科书。三 编写编码规范的一些建议 以下是我对定义编码规范的一些建议:
[*]求同存异 不要妄图改变组织的编码习惯,除非有绝对合理的理由,否则还是以民主为主,毕竟你没有权利要求所有人都沿用你的编码习惯。
[*]定义编码规范越早越好 也早使用编码规范,也早享受其带来的好处。
[*]将规范分为强制部分和推荐部分 求同存异的具体实现。将最基本的规范列放在强制部分,所有成员必须遵守;将好的但不重要的习惯列在推荐部分,开发人员可以根据自己习惯选择是否使用。
[*]编码规范不要太长 太长的文档没人看,所有人都一样,除了礼品单和工资单没人愿意看长的东西,所以编码规范必须精炼,最好是只有2~3页,让开发人员可以打印出来随时查看。
[*]必须是约定俗成的 规范必须是行业中约定俗成的,不要有什么个性化发挥。
四 编码规范参考 我本人不太推荐制定过细的编码规范。制定编码规范是为了增强代码的可读性,毕竟代码的结构才是主要关注问题,所以我的编码规范还是比较简短的。里面只是对可能会破坏编码风格的行为进行约束,而没有细化到“空行”甚至“空格”的级别。
编码规范一 命名空间 <公司名称>.(<产品名称>|<相关技术>)[.<用途>] [.<子命名空间>]二 代码风格
[*]花括号“{}”不允许省略,即使只有一段代码。
[*]不允许省略访问修饰符。
[*]类型默认是密封的。
[*]不允许公开字段。
[*]使用括号“()”来强调运算符优先级。
三 命名规范(一) 类、结构和接口的命名
[*]使用名词或名词短语。
[*]使用Pascal方式。
[*]在接口名称前加上前缀“I”。
[*]考虑在派生类末尾使用基类的名字。
[*]如果该类仅仅为了实现某个接口,那么请保持其与接口命名的统一。
[*]如果从.NET 框架中存在的类型派生的类型,应该遵循以下规范:
基类 派生类
System.Attribute 要给自定义的特性添加“Attribute”后缀
System.Delegate 要给用于事件处理的委托添加“EventHandler”后缀 要给用于事件处理之外的那些委托添加“Callback”后缀 不要给委托添加“Delegate”后缀
System.EventArgs 要添加“EventArgs”后缀
System.Exception 要添加“Exception”后缀
IDictionary,IDictionary<T,V> 要添加“Dictionary”后缀
IEnumerable,ICollection,IList, IEnumerable<T>,ICollection<T>,IList<T> 添加“Collection”后缀
System.IO.Stream 添加“Stream”后缀
CodeAccessPermission,IPermission 添加“Permission”后缀
(二) 成员的命名
成员 大小写 规范
方法 Pascal(公开)、Camel(私有) 用动词或动词短语命名
属性 Pascal 用名词、名词短语或形容词来命名 集合属性应该使用复数形式,而不是添加后缀 用“Is”、“Can”、“Has”等表示布尔属性 可以用属性的类型名来命名属性
事件 Pascal 使用动词或动词短语来命名事件 用现在时和过去时来区分前置和后置事件
字段 Camel(私有) 要用名词、名词短语或形容词来命名 不要加任何前缀
(三) 参数的命名
[*]Camel风格。
[*]要使用left和right来命名重载的二元操作符的参数——如果参数没有具体的含义。
[*]要使用value来命名重载的一元操作符的参数——如果参数没有具体的含义。
[*]不要在参数中使用数字编号。
[*]尽量使用描述性的名字命名泛型类型参数,并在前面使用“T”前缀。
(四) 常量、变量的命名
[*]常量——所有单词大写并用“_”分隔。
[*]局部变量——Camel风格。
(五) 枚举的命名
[*]Pascal风格。
[*]使用名词的复数形式来命名标记枚举。
[*]不要添加“Enum”或“Flag”后缀。
[*]不要给枚举类型值的名字加前缀。
(六) 资源的命名
[*]Pascal风格。
[*]仅使用字母、数字和下划线。
[*]在命名异常消息的资源时,资源标识符应该是异常类型名加上简短的异常标识符。
(七) 数据库命名
[*]表——“模块名_表名”。
[*]字段——bool类型用“Is”、“Can”、“Has”等表示;日期类型命名必须包含“Date”;时间类型必须包含“Time”。
[*]存储过程——使用“proc_”前缀。
[*]视图——使用“view_”前缀。
[*]触发器——使用“trig_”前缀。
(八) XML命名 节点名称使用Pascal风格,属性名称使用Camel风格。四 注释
[*]对接口和复杂代码块必须进行注释。
[*]修改代码时保持注释同步。
[*]未完成的功能使用TODO标记。
[*]修改他人代码时要先注释对方代码,并写明修改原因,不允许随便删除他人代码。
[*]发布前移除无用注释。
五 异常处理
[*]原则上只允许显示抛出InvalidOperationException、ArgumentException、ArgumentNullException和ArgumentOutOfRangeException四种异常类型。
[*]在自定义异常时,必须使用VS提供的代码模板来创建自定义异常。
[*]
页:
[1]