概述
良好的编程风格是代码可靠性的基础。首先,编程规范的意义在于将程序语言限定在一个可靠的范围内,能帮助开发者,从习惯上避免很多容易产生的低级错误。其次,对于团队来讲,统一的编程风格可以增强程序的易读性,减小成员之间的沟通成本。增强程序的可维护性。因此,我们需要制定一套编码规范。
Unity开发中,我们统一使用C#语言,本规范仅限于C#语言。
规范指定原则
1、方便代码的交流和维护
2、不逆天,不与大众习惯冲突。
3、使代码清晰、美观,阅读更方便。
术语定义
Pascal: 一种标识符大小写的方式,每个单词的首字母都大写,其余字母小写。
Camel:一种标识符大小写的方式,第一个单词全部小写,从第二个单词开始首字母大写。
遵守等级:文中对于一条规范,都会着重标出“必须”,“建议”这些字眼,“必须”表示这条规则必须遵守;“建议”表示这条规则可以不遵守,但是请尽量遵守。
编码环境
为统一源代码文件格式,团队需要统一编码环境:
windows下使用Visual Studio 2012
mac 下使用MonoDeveloper
注意:文件行尾需要统一为Windows(CR LF),即如果在vs中打开源代码文件时,出现如下警告,要选“是”然后保存。
在MonoDeveloper中,要在Tools->Options中选择如下选项,保证不再修改行尾符号:
命名规范
编程的过程中,往往不希望在命名问题上耗费太多时间,所以的命名都具有一定的随意性。但是,我们需要统一一些命名原则。命名时不能违背这些原则。
通用命名规则
1、所有文件、类、变量等命名都必须使用英文拼写。不能使用汉语拼音,不能使用数字。
1 2 3 |
int Number = 3; //正确 int Shuzi=3; //错误 int Number1 = 3; //错误 |
2、函数名、变量名、类名都必须具有描述性,尽量不要用缩写。如果用缩写,要保证在项目之外用,别人也能知道缩写的含义是什么。
1 2 3 4 |
int buildingCount; //正确 int n; //错误 int bdnNumber; //错误,因为在程序外,没人知道bdn代表什么。 string ipString; //正确,因为在程序外,大家也知道ip的意思。 |
不要使用省略字母的缩写:
1 2 |
int errorCount //正确 int errorCnt //错误 |
对于短循环中for(i=0; i<3; i++) 中的i,j,k等可以这样用。
文件命名
所有的C#源代码文件,命名都使用英文全拼,都必须遵循Pascal大小写规范。
文件夹命名
Unity工程中所有C#代码的文件夹命名,都必须使用英文全拼,遵循Pascal大小写规范。
场景节点命名
Unity场景中的节点命名,都要使用英文全拼,遵循Pascal大小写规范。
命名空间命名
全英文拼写,遵循Pascal大小写规范。
类型命名
类型包括class 和 struct。类型名必须使用Pascal形式的全英文拼写。不允许出现数字、下划线、或者汉语拼音。例如:
1 2 3 |
class CameraManager //正确 struct cameraManager //错误 class Camera_Manager //错误 |
变量命名
变量命名存在一下几种情况:
1、类的private成员变量和protected成员变量,必须使用m开头的Pascal形式的全英文拼写。不允许出现数字、下划线、或者汉语拼音。例如:
1 2 3 |
private Vector3 mCurrentPosition // 正确 private Vector3 CurrentPosition //错误,首字母应该应该为m。 private Vector3 currentPos //错误,不能使用缩写,不能使用Camel形式大小写。 |
2、类的public成员变量,必须使用Pascal形式全英文拼写。例如:
1 |
public int BuildingCount; |
3、静态成员变量,必须使用s后接Pascal形式的全英文拼写。例如:
1 |
private static Singleton sInstance =null; //正确 |
4、参数变量,必须使用Camel形式的全英文拼写。例如:
1 2 3 |
public void Function(int heroNumber){ } |
5、函数内变量,必须使用Camel形式的全英文拼写。
6、函数内静态变量,同静态成员变量。
常量命名
所有常量(无论是局部、全局、还是类中的)都必须以k开头的Pascal形式的全英文拼写。例如:
1 |
const int kDaysInWeek = 7; |
函数命名
所有函数名称,都应该使用动词或者动词短语构成。大小写采用Pascal。例如:
1 |
public void RemoveAll() |
枚举命名
枚举本身的命名,使用Pascal形式的大小写,枚举中的值采用全大写加下划线”_”的形式。例如:
1 2 3 4 |
enum Direction{ NORTH = 0, NORTH_EAST = 1 } |
注释
为了统一大家的注释习惯,提高注释的可读性,规定一下几个注释原则:
1、在注释中建议使用中文。使用其他语言会增加其他成员的阅读成本。
2、尽量使用代码的自解释,也就是代码本身就是解释。觉得难以理解的部分才使用注释。
3、注释建议使用 //, 尽量少使用/**/。
4、不要将不用的代码当注释处理,如果提交前确定这段代码无效,就必须删掉,不能暂时注释。如果需要查看以前代码,请使用svn。
5、对那些临时的、短期的解决方案,或已经够好但并不完美的代码,建议使用TODO 注释。格式为:// TODO(作者名字):后面要干的事。例如:
// TODO(西门庆):等王妈给牵好线,我再动手。
格式
行长度
每一行代码的行长度,建议不要超过110个字符。如果超过这个长度,可以按照以下规则换行:
1、在逗号后换行。
2、在操作符前换行。
3、第一条优先于第二条。
例如:
1 |
private string GetLongLongLongLongLongLongLong... LongLongLongName(int id,string name); |
缩进
必须使用4个空格而不用Tab缩进,VS需要设置以下选项:
工具->选项->文本编辑器->C#->制表符->插入空格
空格
在以下情况下,必须使用空格:
1、多个参数中,逗号后面要加入空格,例如:
1 |
Function(int id, int count, string name); |
2、除了”.”之外,所有的二元操作符都要用空格与他们的操作数隔开。一元操作符,”++”,”–“,和操作数之间不需要空格。如:
1 2 3 4 5 |
a += c + d; a = (a + b) / (c * d); while(d++ = s++){ n++; } |
4、语句中的表达式之间用空格隔开。例如:
1 |
for(expr1; expr2; expr3) |
花括号{}
花括号的格式,我们必须统一使用UNIX/Linux风格,及将左括号”{“放在行尾,右括号”}”重启一行。这样的代码结构紧凑,节约代码空间,而且美观。有如下几种情况:
1、语句中,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
if (id == 1){ //代码 }else if(id == 2){ //代码 }else{ //代码 } for(int i = 3; i > 0; i++){ //代码 } switch(id){ case 3: break; } |
2、函数和类
1 2 3 4 5 6 7 |
public void Init(){ //代码 } class OneClass : MonoBehaviour{ //代码 } |
在VS中,将下面界面红框中的选项全部去掉。
空行
为保证代码的紧凑和易读性,建议尽量少使用空行,除非以下情况:
1、在类型定义之间加入空行,例如:
1 2 3 4 5 6 7 8 9 |
struct SomeStruct{ //代码 } 空行 class SomeClass{ //代码 } |
2、函数定义之间,例如:
1 2 3 4 5 6 7 8 9 |
public void Function(){ //代码 } //空行========== public void OtherFunction(){ //代码 } |
3、多行代码间,有非常明确的逻辑上的分割,可以加入空行。例如:
//下面的代码在写一段逻辑
武大郎拿起一个烧饼小心地包好
武大郎接过王二麻子的钱
武大郎把烧饼递给王二麻子
武大郎微笑这说:“下次再来啊”
空行============
//下面的代码在写另一段逻辑
西门庆握住了潘金莲的脚
西门庆说:“娘子的脚好漂亮”
潘金莲娇嗔道:“官人好坏”
日志
在代码中加入日志,有助于我们分析代码中的问题,以及监控程序的运行状态。但是在团队开发中,滥用日志,会造成日志输出泛滥,真正重要的信息被淹没在垃圾日志的茫茫大海中。所以必须要规范日志输出。
调试日志
在开发的过程中,需要打出一些临时性的日志配合开发,在开发完毕后,这些日志就没有任何卵用了。这种日志我们称为调试日志。调试日志需要遵守一下规则:
1、建议使用Unity自带的Debug.Log或者Debug.LogFormat。
2、功能开发完毕后必须删除调试日志。建议这些日志不要提交svn。
状态检测日志
有事我们需要在代码中加入一些检测日志,不仅在开发时候使用,也需要在日后程序运行时监控程序的运行状态。这些日志我们称为状态检测日志。状态检测日志需要遵守以下规则:
1、必须使用Logger类进行Log输出,而不能用Unity自带的日志输出接口。Logger提供以下接口:
1 |
void LogInformation(int level, string author, string information) |
参数level:日志等级,按照重要程度分为 1,2,3三级,1级最重要,3级最不重要。
参数author:日志作者,统一使用作者姓名的汉语拼音,全小写。例如:武大郎 wudalang。
参数 information:日志信息,作者自行输出,建议不超过140字。
错误日志
有时,我们需要在程序可能出现错误的地方输出日志。方便出错时查找错误原因。这样的日志我们称为错误日志。,错误日志也必须使用Logger输出,禁止使用Unity原生的Debug.LogError。Logger提供的接口如下:
1 |
LogError(string author, string information) |
参数author:日志作者,同上。
参数infomation:日志内容,同上。
后记
即使上面所有的规定你都不遵守,写出来的代码也能执行。就像一个士兵不遵守所有的军纪也能杀敌人一样。但是一个项目就是一场战争,只有大家严格遵守军纪,才有可能赢得胜利。共勉!