当前位置:   article > 正文

软件设计方案(编程规范总则)_软件设计规范

软件设计规范
 

1、排版

1)程序块要采用缩进风格编写,缩进的空格数为4个,对于由开发工具自动生成的代码可以不一致;

2)相对独立的程序块之间、变量说明之后必须加空行;

3)较长的语句要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读;

4)循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分,同3);

5)若函数或过程中的参数较长,也要进行适当的划分;

6)不允许把多个短语句写在一行中,即一行只写一条语句;

7)iffordowhilecaseswitchdefault等语句自占一行,且iffordowhile等语句的执行语句部分无论多少都要加括号{};

8)对齐只使用空格键,不使用TAB键;

9)函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格,case语句下的处理语句也要遵从语句缩进要求;

10)程序块的分界符(如大括号‘{’和‘}’)应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类的定义、结构的定义、枚举的定义以及iffordowhileswitchcase语句中的程序都要采用如上的缩进方式;

11)在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格,但不要连续留两个以上空格。进行非对等操作时,如果是关系密切的操作符(如->)后不应加空格。

采用这种松散方式编写代码的目的是使代码更加清晰,在已经非常清晰的语句中没有必要再留空格。如果语句已足够清晰,则括号内侧(即左括号后面和右括号前面)不需要加空格,多重括号间也不必加空格。 在长语句中,如果需要加的空格非常多,那么应该保持整体清晰,而在局部不加空格。

(1)逗号、分号只在后面加空格。

int a, b, c;  

(2)比较操作符、赋值操作符、算术操作符、逻辑操作符、位操作符等双目操作符的前后加空格。

a = b + c;

a *= 2;

a = b ^ 2;

(3)"!"、"~"、"++"、"--"、"&"(地址运算符)等单目操作符前后不加空格。

flag = !isFull;

p = &com;       

i++;            

(4)"->"、"."前后不加空格。

(5)ifforwhileswitch等与后面的括号间应加空格,使if等关键字更为突出、明显。

if (a >= b && c > d)

12)一行程序以小于80字符为宜,不要写得过长。

2、注释

注释应该说明代码的目的,要讲清为什么要那么做,而不是怎么去做。 1)一般情况下,源程序有效注释量必须在20%以上。注释的原则是有助于对程序的阅读理解,在该加的地方都加,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁;

2)注释格式尽量统一,建议使用“/* …… */”;

3)说明性文件(如头文件.h文件、.inc文件等)头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系等,头文件的注释中还应有函数功能简要说明;

4)源文件头部应进行注释,列出:版权说明、版本号、生成日期、作者、模块功能、主要函数及其功能等;

5)函数头部应进行注释,列出:函数功能、输入参数、输出参数、返回值等;

6)边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性;

7)避免在注释中使用缩写,特别是非常用的缩写。如无法避免,应对缩写进行必要的说明;

8)注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,如放于上方则需与其上面的代码用空行隔开;

9)变量、常量、宏的注释有时也是必须的,应放在其上方相邻位置或右方;

10)数据结构声明(包括数组、结构、类、枚举等),如果其命名不是充分自注释的,必须加以注释。对数据结构的注释应放在其上方相邻位置,对结构中的每个域的注释放在此域的右方;

11)全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它以及存取时注意事项等的说明;

12)将注释与其上面的代码用空行隔开,注释与所描述内容进行同样的缩排;

13)对变量的定义和分支语句(条件分支、循环语句等)必须编写注释。这些语句往往是程序实现某一特定功能的关键,对于维护人员来说,良好的注释帮助更好地理解程序,有时甚至优于看设计文档;

14)通过对函数或过程、变量、结构等正确的命名以及合理地组织代码的结构,使代码成为自注释的,减少不必要的注释;

15)当代码段较长,特别是多重嵌套时,在程序块的结束行右方加注释标记,以表明某程序块的结束;

16)建议注释多使用中文,除非能用非常流利准确的英文表达。

3、标识符命名

1)标识符的命名要清晰明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。较长的单词可取单词的头几个字母形成缩写,一些单词有大家公认的缩写;

2)命名中若使用特殊约定或缩写,应该在源文件的开始之处,进行必要的注释说明;

3)命名风格要自始至终保持一致;

4)对于变量命名,禁止取单个字符(如i、j、k...)。单个字符容易敲错,且编译时又不易检查出来。建议除了要有具体含义外,还能表明其变量类型、数据类型等,但i、j、k作局部循环变量是可以的;

5)命名规范必须与所使用的系统风格保持一致,并在同一项目中统一。除非必要,不要用数字或较奇怪的字符来定义标识符;

6)在同一软件产品内,应规划好接口部分标识符(变量、结构、函数及常量)的命名,防止编译、链接时产生冲突;

7)用正确的反义词组命名具有互斥意义的变量或相反动作的函数等;

下面是一些在软件中常用的反义词组:

add / remove       begin / end         create / destroy

insert / delete       add / delete         get / release

increment / decrement                  put / get

lock / unlock       open / close         first / last  

min / max          old / new          start / stop

next / previous      send / receive       show / hide

source / target       source / destination

cut / paste          up / down

8)除了特殊应用,应避免使用以下划线开始和结尾的定义。

4、可读性

1)注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级;

2)避免使用不易理解的数字,用有意义的标识来替代;

3)源程序中关系较为紧密的代码应尽可能相邻,便于程序阅读和查找;

4)不要使用难懂的技巧性很高的语句,除非很有必要时。程序的高效率并不等同于语句的高技巧,而在于算法。

5、变量与结构

1)去掉没必要的公共变量,以降低模块间的耦合度;

2)仔细定义并明确公共变量的含义、作用、取值范围及公共变量间的关系;

3)明确公共变量与操作此公共变量的函数或过程的关系,如访问、修改及创建等。这种关系的说明可在注释或文档中描述;

4)当向公共变量传递数据时,要十分小心,防止赋与不合理的值或越界等现象发生。若有必要应进行合法性检查,以提高代码的可靠性、稳定性;

5)构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的公共变量,防止多个不同模块或函数都可以修改、创建同一公共变量的现象;

6)使用严格形式定义的、可移植的标准数据类型,尽量不要使用与具体硬件或软件环境关系密切的变量;

7)结构的功能要单一,是针对一种事务的抽象。结构中的各元素应代表同一事务的不同侧面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构中;

8)不同结构间的关系不要过于复杂,否则应合为一个结构;

9)仔细设计结构中元素的布局与排列顺序,使结构容易理解、节省占用空间,并减少引起误用的现象;

10)结构的设计要尽量考虑向前兼容和以后的版本升级,并为某些未来可能的应用保留余地;

11)留心具体语言及编译器处理不同数据类型的原则及有关细节;

12)编程时,要注意数据类型的强制转换。对编译系统默认的数据类型转换要有充分的认识,尽量减少没有必要的数据类型默认转换与强制转换,合理地设计数据并使用自定义数据类型,避免数据间进行不必要的类型转换;

13)对自定义数据类型进行恰当命名,使它成为自描述性的,以提高代码可读性,但要注意其命名方式在同一产品中的统一。

6、函数与过程

1)设计高扇入、合理扇出(小于7)的函数。较良好的软件结构通常是顶层函数的扇出较高,中层函数的扇出较少,而底层函数则扇入到公共模块中;

2)函数的规模尽量限制在200行以内,不包括注释和空格行;

3)对所调用函数的错误返回码要仔细、全面地处理;

4)在同一项目组应明确规定对接口函数参数的合法性检查应由函数的调用者负责还是由接口函数本身负责,缺省是由函数调用者负责;

5)防止将函数的参数作为工作变量。对必须改变的参数,最好先用局部变量代之,再将该局部变量的内容赋给该参数;

6)一个函数仅完成一件功能,不要设计多用途的函数。函数名应准确描述函数的功能;

7)函数的功能应该是可以预测的,也就是说只要输入数据相同就应产生同样的输出;

8)避免设计多参数函数,不使用的参数从接口中去掉,减少函数间接口的复杂度;

9)非调度函数应减少或防止控制参数,尽量只使用数据参数,防止函数间的控制耦合;

10)检查函数所有参数输入与非参数输入的有效性;

11)在编程时,经常遇到在不同函数中使用相同的代码,许多开发人员都愿把这些代码提出来,并构成一个新函数。若这些代码关联较大并且是完成一个功能的,那么这种构造是合理的,否则这种构造将产生随机内聚的函数;

12)功能不明确且较小的函数,特别是仅有一个上级函数调用它时,应考虑把它合并到上级函数中,而不必单独存在;

13)减少函数本身或函数间的递归调用。除非为某些算法或功能的实现方便,应减少没必要的递归调用;

14)仔细分析模块的功能及性能需求,并进一步细分,若有必要画出有关数据流图,据此来进行模块的函数划分与组织;

15)对于提供了返回值的函数,在引用时最好使用其返回值;

16)当一个过程(函数)中对较长变量(一般是结构的成员)有较多引用时,可以用一个意义相当的宏代替。

7、可测性

1)在同一项目组或产品组内,要有一套统一的为集成测试与系统联调准备的调测开关及相应打印函数,并且要有详细的说明;

2)在同一项目组或产品组内,调测打印出的信息串的格式要有统一的形式。信息串中至少要有所在模块名(或源文件名)及行号;

3)编程的同时要为单元测试选择恰当的测试点,并仔细构造测试代码、测试用例,同时给出明确的注释说明。测试代码部分应作为(模块中的)一个子模块,以方便测试代码在模块中的安装与拆卸(通过调测开关);

4)使用断言来发现软件问题,提高代码可测性。用断言来检查程序正常运行时不应发生但在调测时有可能发生的非法情况,但不能用断言来检查最终产品肯定会出现且必须处理的错误情况;

5)对较复杂的断言加上明确的注释,用断言确认函数的参数,保证没有定义的特性或功能不被使用,对程序开发环境的假设进行检查;

6)正式软件产品中应把断言及其它调测代码去掉(即把有关的调测开关关掉),以加快软件运行速度;

7)在软件系统中设置与取消有关测试手段,不能对软件实现的功能等产生影响;

8)用调测开关来切换软件的DEBUG版和正式版,而不要同时存在正式版本和DEBUG版本的不同源文件,以减少维护的难度;

9)软件的DEBUG版本和发行版本应该统一维护,不允许分家,并且要时刻注意保证两个版本在实现功能上的一致性;

10)在编写代码之前,应预先设计好程序调试与测试的方法和手段,并设计好各种调测开关及相应测试代码如打印函数等;

11)调测开关应分为不同级别和类型。针对模块或系统某部分代码的调测,针对模块或系统某功能的调测,对性能、容量等的测试;

12)编写防错程序,然后在处理错误之后可用断言宣布发生错误。

8、程序效率

1)在保证软件系统的正确性、稳定性、可读性及可测性的前提下提高代码效率,包括全局效率、局部效率、时间效率及空间效率;

2)局部效率应为全局效率服务,不能因为提高局部效率而对全局效率造成影响;

3)通过对系统数据结构的划分与组织的改进,以及对程序算法的优化来提高空间效率;

4)仔细考虑循环体内的语句是否可以放在循环体之外,使循环体内工作量最小,从而提高程序的时间效率;

5)仔细考查、分析系统及模块处理输入(如事务、消息等)的方式,并加以改进;

6)对模块中函数的划分及组织方式进行分析、优化,改进模块中函数的组织结构,提高程序效率;

7)不应花过多的时间拼命地提高调用不很频繁的函数代码的效率;

8)仔细地构造或直接用汇编编写调用频繁或性能要求极高的函数。嵌入汇编可提高时间及空间效率,但也存在一定风险;

9)在保证程序质量的前提下,通过压缩代码量、去掉不必要代码以及减少不必要的局部和全局变量,来提高空间效率;

10)尽量减少循环嵌套层次。在多重循环中,应将最忙的循环放在最内层,以减少CPU切入循环层的次数;

11)避免循环体内含判断语句,应将循环语句置于判断语句的代码块之中;

12)尽量用乘法或其它方法代替除法,特别是浮点运算中的除法;

13)不要一味地追求紧凑的代码,因为紧凑的代码并不代表高效的机器码。

9、质量保证

1)在软件设计过程中构筑软件质量;

2)代码质量保证优先原则

(1)正确性,指程序要实现设计要求的功能;

(2)稳定性/安全性,指程序稳定、可靠、安全;

(3)可测试性,指程序要具有良好的可测试性;

(4)规范/可读性,指程序书写风格、命名规则等要符合规范;

(5)全局效率,指软件系统的整体效率;

(6)局部效率,指某个模块、子模块、函数的本身效率;

(7)个人表达方式,指个人编程习惯。

3)只引用属于自己的存贮空间;

4)防止引用已经释放的内存空间;

5)过程/函数中分配的内存,在过程/函数退出之前要释放;

6)过程/函数中申请的(为打开文件而使用的)文件句柄,在过程/函数退出之前要关闭;

7)防止内存操作越界;

8)认真处理程序所能遇到的各种出错情况;

9)系统运行之初,要初始化有关变量及运行环境,防止未经初始化的变量被引用,并对加载到系统中的数据进行一致性检查;

10)严禁随意更改其它模块或系统(不属于自己)的有关设置和配置,不能随意改变与其它模块的接口;

11)注意易混淆的操作符。当编完程序后,应从头至尾检查一遍这些操作符,以防止拼写错误;

12)有可能的话,if语句尽量加上else分支,对没有else分支的语句要小心对待。switch语句必须有default分支;

13)不使用与硬件或操作系统关系很大的语句,而使用建议的标准语句,以提高软件的可移植性和可重用性;

14)精心构造算法,并对其性能、效率进行测试,对较关键的算法最好使用其它算法来确认;

15)注意表达式是否会上溢、下溢,使用变量时要注意其边界值;

16)系统应具有一定的容错能力,对一些错误事件(如用户误操作等)能进行自动补救;

17)对一些具有危险性的操作代码要仔细考虑,防止对数据、硬件等的安全构成危害,以提高系统的安全性。

10、代码编辑、编译与审查

1)同产品软件(项目组)内,最好使用相同的编辑器,并使用相同的设置选项;

2)打开编译器的所有告警开关对程序进行编译;

3)通过代码走读及审查方式对代码进行检查;

4)编写代码时要注意随时保存,并定期备份,防止由于断电、硬盘损坏等原因造成代码丢失;

5)某些语句经编译后产生告警,如果你认为它是正确的,那么应通过某种手段去掉告警信息;

6)使用代码检查工具对源程序检查,使用软件工具进行代码审查。

11、代码测试与维护

1)单元测试要求至少达到语句覆盖;

2)整理或优化后的代码要经过审查及测试;

3)代码版本升级要经过严格测试;

4)使用工具软件对代码版本进行维护;

5)正式版本上软件的任何修改都应有详细的文档记录;

6)发现错误立即修改,并且要记录下来;

7)关键的代码在汇编级跟踪;

8)仔细设计并分析测试用例,使测试用例覆盖尽可能多的情况,以提高测试用例的效率;

9)尽可能模拟出程序的各种出错情况,对出错处理代码进行充分的测试;

10)仔细测试代码处理数据、变量的边界情况;

11)保留测试信息,以便分析、总结经验及进行更充分的测试;

12)不应通过“试”来解决问题,应寻找问题的根本原因;

13)对自动消失的错误进行分析,搞清楚错误是如何消失的;

14)测试时应设法使很少发生的事件经常发生;

15)明确模块或函数处理哪些事件,并使它们经常发生;

16)坚持在编码阶段就对代码进行彻底的单元测试,不要等以后的测试工作来发现问题;

17)去除代码运行的随机性,让函数运行的结果可预测,并使出现的错误可再现。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/989751
推荐阅读
相关标签
  

闽ICP备14008679号