认识C#编程规范.docx
《认识C#编程规范.docx》由会员分享,可在线阅读,更多相关《认识C#编程规范.docx(25页珍藏版)》请在冰豆网上搜索。
认识C#编程规范
认识C#编程规范
∙摘要:
《亮剑.NET.图解C#开发实战》采用全新的图解思路,分3篇介绍使用微软C#语言开发实际应用程序的基本知识。
第18章讲述C#项目开发规范与三层架构。
本节说的是认识C#编程规范。
第18章C#项目开发规范与三层架构
使用C#进行大型项目开发时,不仅需要技术支持,还需要一定的开发理念和项目规范,对于C#来言,大型项目的开发理念是三层结构模式,项目规范则包括命名、格式、注释、文档、标准等,本章则从编程规范和开发模式上论述项目开发方面的技术。
主要包括以下内容:
规范化命名。
编码规范。
用户界面规范。
三层结构的搭建。
18.1 认识C#编程规范
软件开发的最终成果通常以可执行文件、代码、用户手册、相关培训和服务等形式体现,其中核心是代码。
编程规范主要体现在对代码中命名规则、缩进、换行和注释等方面提出的要求,同时还包括程序结构方面的规定。
C#编程规范基本要求如下。
1.程序结构要求
程序结构清晰,简单易懂,单个函数的程序行数不得超过100行。
打算干什么,要简单,直接了当,代码精简,避免垃圾程序。
尽量使用.NET库函数和公共函数(无特殊情况不要使用外部方法调用Windows的核心动态链接库)。
不要随意定义全局变量,尽量使用局部变量。
2.可读性要求
可读性第一,效率第二(代码是给人读的)。
保持注释与代码完全一致。
每个源程序文件,都有文件头说明,说明规格见规范。
每个函数,都有函数头说明,说明规格见规范。
主要变量(结构、联合、类或对象)定义或引用时,注释能反映其含义。
处理过程的每个阶段都有相关注释说明。
在典型算法前都有注释,同时算法在满足要求的情况下尽可能简单。
利用缩进来显示程序的逻辑结构,缩进量一致并以"Tab"键为单位,定义Tab为6个字节。
循环、分支层次不要超过5层。
注释可以与语句在同一行,也可以在上行。
空行和空白字符也是一种特殊注释。
一目了然的语句不加注释。
注释的作用范围可以为定义、引用、条件分支及一段代码。
注释行数(不包括程序头和函数头说明部份)应占总行数的1/5到1/3。
常量定义(DEFINE)有相应说明。
3.结构化要求
禁止出现两条等价的支路。
禁止GOTO语句。
用IF语句来强调只执行两组语句中的一组。
禁止ELSEGOTO和ELSERETURN,用CASE实现多路分支。
避免从循环引出多个出口。
函数只有一个出口。
不使用条件赋值语句。
避免不必要的分支。
不要轻易用条件分支去替换逻辑表达式。
4.正确性与容错性要求
程序首先是正确,其次是优美。
无法证明你的程序没有错误,因此在编写完一段程序后,应先回头检查。
改一个错误时可能产生新的错误,因此在修改前首先考虑对其他程序的影响。
所有变量在调用前必须被初始化。
对所有的用户输入,必须进行合法性检查。
不要比较浮点数的相等,如10.0*0.1==1.0,不可靠。
程序与环境或状态发生关系时,必须主动去处理发生的意外事件,如文件能否逻辑锁定、打印机是否联机等,对于明确的错误,要有明确的容错代码提示用户。
单元测试也是编程的一部份,提交联调测试的程序必须通过单元测试。
尽量使用规范的容错语句。
例如:
5.可重用性要求
重复使用的完成相对独立功能的算法或代码应抽象为ASP.NET服务或类。
ASP.NET服务或类应考虑OO思想,减少外界联系,考虑独立性或封装性。
18.1.1 如何规范化命名
选择正确名称时的困难可能表明需要进一步分析或定义项的目的。
使名称足够长以便有一定的意义,并且足够短以避免冗长。
唯一名称在编程上仅用于将各项区分开,表现力强的名称是为了帮助人们阅读。
因此,提供人们可以理解的名称是有意义的。
不过,要保证选择的名称符合适用语言的规则和标准。
1.变量(Variable)命名规范
程序中变量名称=变量的前缀+代表变量含义的英文单词或单词缩写。
类模块级的变量以"m_"作前缀,例如:
1.public class hello
2.{
3. private string m_Name;
4. private DateTime m_Date;
5.}
类的属性所对应的变量,采用属性名前加"m_"前缀的形式,例如:
1.public class hello
2.{
3. private string m_Name;
4. public string Name
5. {
6. get
7. {
8. return m_Name;
9. }
10. }
11.}
过程级的变量不使用前缀,例如:
1.public class hello
2.{
3. void say()
4. {
5. string SayWord;
6. }
7.}
过程的参数使用"p_"作为参数,例如:
1.public class hello
2.{
3. void say(string p_SayWord)
4. {
5. }
6.}
针对异常捕获过程中的Exception变量命名,在没有冲突的情况下,统一命名为e;如果有冲突的情况下,可以重复e,比如ee。
如果捕获异常不需要进行任何处理,则不需要定义Exception实例,例如:
1.try
2. {
3. ……
4. }
5. catch( Exception )
6. {
7. }
8.}
鉴于大多数名称都是通过连接若干单词构造的,请使用大小写混合的格式以简化它们的阅读。
每个单词的第一个字母都要大写。
即使对于可能仅出现在几个代码行中的生存期很短的变量,仍然使用有意义的名称。
仅对于短循环索引使用单字母变量名,如i或j。
在变量名中使用互补对,如min/max、begin/end和open/close。
不要使用原义数字或原义字符串,如fori=1To7。
而是使用命名常数,如Fori=1ToNUM_DAYS_IN_WEEK以便于维护和理解。
2.控件命名规则
控件命名=Web控件缩写前缀+"_"+变量名。
控件命名规则如表18-1所示。
表18-1 控件命名规则
控件
缩写
控件
缩写
Label
lbl
Button
cmd
TextBox
txt
ListBox
lst
CheckBox
chk
DropDownList
drp
3.常量命名规范
常量名也应当有一定的意义,格式为NOUN或NOUN_VERB。
常量名均为大写,字之间用下画线分隔。
例如:
1.private const bool WEB_ENABLEPAGECACHE_DEFAULT = true;
2.private const int WEB_PAGECACHEEXPIRESINSECONDS_DEFAULT = 3600;
3.private const bool WEB_ENABLESSL_DEFAULT = false;
变量名和常量名最多可以包含255个字符,但是,超过25到30个字符的名称比较笨拙。
此外,要想取一个有实际意义的名称,清楚地表达变量或常量的用途,25或30个字符应当足够了。
4.类(Class)命名规范
名字应该能够标识事物的特性。
名字尽量不使用缩写,除非它是众所周知的。
名字可以由两个或3个单词组成,但通常不应多于3个。
在名字中,所有单词第一个字母要大写。
例如,IsSuperUser,包含ID的,ID全部大写,如CustomerID。
使用名词或名词短语命名类。
少用缩写。
不要使用下画线字符(_)。
例如:
1.public class FileStream;
2.public class Button;
3.public class String;
5.接口(Interface)命名规范
与类命名规范相同,唯一区别是接口在名字前加上"I"前缀,例如:
1.interface IDBCommand;
2.interface IButton;
18.1.2 代码格式
代码缩进使用"保留制表符",而不是"插入空格"。
在VS2005开发界面中,选择"工具"→"选项"菜单命令,打开"选项"对话框,选中"保留制表符"单选按钮,如图18-1所示。
在代码中垂直对齐左大括号和右大括号,例如:
1.if(x==0)
2.{
3. Response.Write("用户编号必须输入!
");
4.}
5.
6.不允许以下情况:
7.
8.if(x==0) {
9. Response.Write("用户编号必须输入!
");
10.}
11.
12.或者:
13.
14.if(x==0){ Response.Write("用户编号必须输入!
");}
为了防止在阅读代码时滚动源代码编辑器,每行代码或注释在1024800的显示频率下不得超过一显示屏。
当一行被分为几行时,通过将串联运算符放在每一行的末尾而不是开头,清楚地表示没有后面的行是不完整的。
每一行上放置的语句不得超过一条。
在大多数运算符之前和之后使用空格,这样做时不会改变代码的意图却可以使代码容易阅读。
例如:
1.int j = i + k;
2.而不应写为:
3.int j=i+k;
将大的复杂代码节分为较小的、易于理解的模块。
编写SQL语句时,对于关键字使用首字母大写,对于数据库元素(如表、列和视图)使用大小写混合。
将每个主要的SQL子句放在不同的行上,这样更容易阅读和编辑语句,例如:
1.SELECT FirstName, LastName
2.FROM Customers
3.WHERE State ='WA'
18.1.3 如何规范化注释
注释对于增加程序的易读性和可维护性非常重要,同时在编程的过程中,也有助于程序员使其思路更加清晰,降低出现逻辑错误的几率。
对于注释的风格,往往采取下面的策略。
1.文件级注释
文件级注释在于说明整个代码文件的功能,常常还包含作者信息、创建日期信息等,便于代码的后期维护。
一个典型的文件级注释如下所示。
上面示例给出了一个较为典型的文件级注释,读者可以根据自身的情况,指定统一的注释规范。
2.函数级注释
函数级注释用于说明某个函数具体完成的功能、输入参数类型、输出结果等信息,便于函数的调用。
一个典型的函数级注释如下所示。
VS.NET开发环境可以自动生成这个风格的函数注释,只需要在方法前输入"//",VS.NET就自动生成注释框架,开发者只需要在相应的地方填入相应的值就可以了。
这种风格的注释还有其他优点,即当开发者使用这个方法时,VS.NET会给出提示信息。
根据上面的例子,在使用SetInfomation方法时VS.NET给出的提示信息。
3.代码功能块级注释
在逻辑严密的方法实现中,常常是一个代码块完成一个特定的子问题,称这样一个代码块为功能块。
对于函数的功能块添加注释可以理顺整个函数的功能,尤其体现在行数较多的函数中。
如下面的示例所示。
如上面的示例,代码功能块级的注释往往可以注释到这个功能块的上面一行,而各个功能块之前使用空行来分隔。
有了这样的功能块注释,整个函数的实现逻辑显得更为清晰,便于从整体上把握函数的实现,避免在实现一些逻辑复杂的功能时出现混乱。
4.代码行级注释
除了上面3种注释,还需要在代码行上加必要的注释以进一步增强代码的可读性,当然,并不需要在每一行上都加注释,只需要在比较复杂的某些行上加以注释即可。
代码行级的注释往往加在本行的后面,如下所示。
18.1.4 管理文档
对于一个较大型的系统工程而言,在开发过程中,从开始的需求分析到最终的代码实现、系统测试,会产生大量的文档,这些文档非常重要,同时又难于管理。
在开发的过程中,对程序员而言,往往由于专注于系统实现而忽视项目文档的管理,希望到了工程结束后统一整理,结果很不理想。
因此,对于项目组而言,需要指定统一的文档管理规范,以保证在开发过程中快速而有序地对文档进行管理。
同时,有了必要的规范,文档的管理也会显得更加轻松。
具体的文档管理规范似乎无统一的标准,对于项目组的全体人员,特别是项目进度管理人员而言,有责任根据自身的情况,制定统一的规范。
18.1.5 实施标准
在制定了开发标准之后,在项目组中实施时可能会遇到一些阻碍,一些具有丰富经验的程序员可能不愿意遵守某些制定好的规范,一是因为他们可能有自己多年的个人习惯,二是因为制定标准的人员可能不具有丰富的开发经验,进而可能会制定一些意义不大的规范。
而如果是通过集体讨论来决定开发标准时,又有可能造成意见的不统一。
无论如何,只要最后工程能够顺利完成,大家总会接受这个标准,反对者们也会发现标准的合理性,并觉得带着一些保留去遵循这一标准是值得的。
如果没有自愿的合作,可以制定需求:
标准一定要经过代码的检验。
18.2 三层结构开发模式
三层结构是基于模块化程序设计的思想,为实现分解应用程序的需求,而逐渐形成的一种标准模式的模块划分方法。
三层架构的优点在于不必为了业务逻辑上的微小变化而迁至整个程序的修改,只需要修改商业逻辑层中的一个函数或一个过程;增强了代码的可重用性;便于不同层次的开发人员之间的合作,只要遵循一定的接口标准就可以进行并行开发了,最终只要将各个部分拼接到一起构成最终的应用程序。
本节将主要介绍三层结构的基本概念及如何搭建三层结构。
18.2.1 三层结构概念
三层结构通常是指数据访问层、业务逻辑层和表示层。
三层结构之间的关系如图18-2所示。
表示层位于最上层,用于显示和接收用户提交的数据,为用户提供交互式的界面。
表示层一般为Windows窗体应用程序或Web应用程序。
业务逻辑层是表示层和数据访问层之间沟通的桥梁,主要负责数据的传递和处理。
数据访问层主要实现对数据的读取、保存和更新等操作。
在三层结构中,各层之间相互依赖,表示层依赖于业务逻辑层,业务逻辑层依赖于数据访问层。
18.2.2 如何搭建三层结构
本节将通过一个简单的登录功能实现,讲述如何搭建三层结构。
1.搭建数据访问层
(1)打开VS2005开发环境,依次选择"文件"→"新建"→"项目"命令,如图18-3所示。
(2)在打开的"新建项目"对话框中,选择项目类型为"VisualStudio解决方案",选择模板为"空白解决方案"。
然后填写解决方案的名称为"MyBookShop",并指定保存位置,如图18-4所示。
(3)在"解决方案资源管理器"中,在解决方案名称上单击鼠标右键,在弹出的快捷菜单中选择"添加"→"新建项目"命令,如图18-5所示。
(4)在打开的"新建项目"对话框中,选择项目类型为"VisualC#",选择模板为"类库"。
填写项目的名称为"MyBookShop.DAL",该项目用于实现数据访问层。
此时项目的保存位置已经默认输入了,是刚才创建空白解决方案时产生的路径,如图18-6所示。
2.搭建业务逻辑访问层
搭建业务逻辑层的步骤与搭建数据访问层类似,不同的是需要重新填写项目名称为"MyBookShop.BLL",如图18-7所示。
3.搭建表示层
(1)在"解决方案资源管理器"中,在解决方案名称上单击鼠标右键,在弹出的快捷菜单中选择"添加"→"新建网站"命令,如图18-8所示。
(2)在打开的"添加新网站"对话框中,选择"ASP.NET网站",选择位置为"文件系统",并设置网站的路径,如图18-9所示。
在三层结构开发中,通常还会使用模型层。
模型层包含所有与数据库中的表相对应的实体类。
表示层、业务逻辑层和数据访问层三层之间通过传递实体对象来达到数据传递的目的。
创建模型层的步骤与搭建业务逻辑层和数据访问层类似,不同的是需要重新填写项目名称为"MyBookShop.Models",如图18-10所示。
此时,在"解决方案资源管理器"中,三层结构的基本框架如图18-11所示。
4.添加各层之间依赖关系
此时,虽然三层结构的基本框架已经搭建成功,但是各层之间是独立的。
只有添加依赖关系,才能让它们相互协作。
(1)添加表示层对业务逻辑层及模型层的依赖。
在"解决方案资源管理器"中,在表示层上单击鼠标右键,在弹出的快捷菜单中选择"添加引用"命令,如图18-12所示。
(2)在打开的"添加引用"对话框中,选择"项目"选项卡,选中项目名称为"MyBookShop.BLL"和"MyBookShop.Models"的两个项目,单击"确定"按钮,如图18-13所示。
(3)使用上述方法在业务逻辑层中添加对数据访问层和模型层的依赖,以及数据访问层对模型层的依赖。
该部分视频教程位置如图18-14所示。
至此,三层结构及各层之间的依赖关系创建完毕。
下面以登录为例,测试各层之间如何协同工作的。
1)编写实体类User.cs
在模型层中,将默认的类名Class1.cs重命名为"User.cs",该实体类与数据库BookShop中的表Users相对应。
实体类User.cs中部分代码如下:
2)编写数据访问类UserService
针对模型层中的每个实体类,数据访问层有一个对应的数据访问类。
例如,针对User实体类,创建一个对应的UserService类,用于对数据表Users的数据处理。
在UserService类中添加一个根据登录名进行查询的方法,代码如下:
在上述代码中,数据访问类中使用了DBHelper类,该类包含了常用的对数据库进行操作的方法。
由于篇幅所限在此不列出具体代码,读者可以查看源代码。
3)编写业务逻辑类UserManager
针对模型层中的每个实体类,业务逻辑层中也有一个对应的类。
例如,针对User实体类,创建一个对应的UserManager类。
在UserManager类中添加用于登录验证的业务方法,其代码如下:
4)编写表示层
(1)创建页面Login.aspx,其设计视图如图18-15所示。
(2)双击"登录"按钮,生成其Click事件,并在代码后置文件Login.aspx.cs中编写事件处理程序,其代码如下:
运行程序前,还需设置启动项目。
在"解决方案资源管理器"中的表示层上单击鼠标右键,在弹出的快捷菜单中选择"设为启动项目"命令,将表示层设置为启动项目,如图18-16所示。
运行程序,输入登录名"admin",输入密码"123456",单击"登录"按钮后,页面跳转到Default.aspx,显示登录成功。
18.3 本章小结
本章首先介绍了C#编程规范,遵循这些规范对项目的开发和维护都起到非常重要的作用;然后介绍了三层结构开发模式,并通过示例演示了如何搭建三层结构。
希望通过本章的学习,读者能够掌握三层结构开发的基本思想和步骤,并为后续实例的学习打下基础。