CAST 源代码命名规范手册 v1.1
Pascal 命名:每一个单词首字母必须大写
Camel 命名:第一个单词首字母小写,其余单词首字母必须大写。
- 任何命名必须优先使用英文单词表达意思,若不是国际公认单词,禁止使用单词缩写进行命名;
- 第二选择是拼音命名,请在命名旁边写上中文注释,避免同音词的困扰;
- 禁止使用任何中文作为命名;
目的
命名的目的是为了提高代码可读性,不仅能提高自身编程素养,同时你也成为别人的榜样。我们要懂得养成利他精神,而不只是利己。不要成为别人眼中那个挖坑和被吐槽的对象,严格命名,从我做起。
解决方案(Solution)
每一个项目都需要有一个代号,因此需要由这个代码作为解决方案的名字或前缀。
举例
- MVC.sln
- MVC.AspNet.sln
- MVC.XXXX.xxxxxx.sln
命名空间
- 必须采用 Pascal 方式;
- 使用名词;
- 必须使用全称;国际公认的单词除外,例如 IP;
- 不允许使用前缀;
- 不允许使用下划线;
- 不允许使用数字;
多级可使用“.”分割,例如 Microsoft.AspNet.Mvc
命名空间必须遵守以下规定:
- 第一级必须是 CCTV,表示公司的缩写;
- 第二级必须是当前项目的代号;
- 第三级根据项目分层职责进行命名(可参考《研发架构.png》)
- 服务层:Services
- 应用层:ApplicationServices
- 领域层:Domains
- 基础设施层:Infrastructures
- 数据传输层:DataTransfers
- 事件层:Events
- 其他层级根据自己需要自行划分
公共组件或组件可斟酌第2、3层
示例
- 正确
- CAST.Notimes.Services
- CAST.FlightPlan.Services.Controllers
- 错误
- CAST.BLL
- CAST.DAL
类(class)
- 必须采用 Pascal 方式;
- 使用名词或短语,主要表示当前类的功能概括;
- 必须使用全称;国际公认的单词除外,例如 IP;
- 不允许使用前缀;
- 不允许使用下划线;
- 不允许使用数字;
举例
-
正确
- public class Utility
- internal class SqlHelper
- protected class EntityBase
-
错误
- public class GetMainClass
- internal class _MyClass
- protected class 2EntityBase
- protected class Entity2Model
类注释(summary)
- 必须要在类开头使用 summary 注释;
- 尽量使用抽象语境的词语,描述类的大概功能;
- 若有需要,请在 summary 中写明备注;
举例说明
-
例1
/// <summary> /// 表示封装常用的方法。 /// <para> /// 这里的方法都是静态的,可以直接调用。 /// </para> /// <remark>方法必须都定义为静态方法。</remark> /// </summary> public class Utility { }
-
例2
/// <summary> /// 表示操作数据库的辅助工具。 /// <para> /// 只能操作 Sql Server 数据库,若想操作 MySql 数据库,请使用 <see sref="MySqlHelper" /> 类。 /// </para> /// </summary> public class SqlHelper { }
接口(interface)
- 必须使用**大写字母“I”**作为前缀;
- 必须采用 Pascal 方式;
- 尽量使用名词或名词短语作为名称;
- 必须使用全称;国际公认的单词除外,例如 IP;
- 不允许使用下划线;
- 不允许使用数字;
举例
-
正确
- public interface IRepository;
- public interface IDbContext;
- public interface IKeywordQuery
-
错误
- public interface Irepository;
- public interface ISql_Context;
- public interface I12306Base
接口注释(summary)
- 尽量使用**“表示…的功能”或“提供…的功能”**等抽象的词语;
- 若接口需要作为泛型约束,请写明备注;
举例说明
- 例1
/// <summary>
/// 提供对数据进行持久化存储的功能。
/// </summary>
public interface IRepository { }
- 例2
/// <summary>
/// 表示继承自该接口的都是实体类型。
/// </summary>
public interface IEntity { }
枚举(enum)
- 必须使用 Pascal 方式;
- 不允许使用 Enum 或 Flag 作为后缀,而要使用名词复数形式,“s” 或 “es” 作为后缀,例如 OrderTypes
- 尽量给枚举自定义值;
- 必须有一个默认值的项,可以使用 None = 0 或 Unknow = 0;
举例说明
- 正确
- public enum ContentCategories
- public enum OrderTypes
- 错误
- public enum OrderFlag
- public enum TypeEnum
枚举注释(summary)
- 请使用抽象词语,并描述清楚使用场景;
- 每一个枚举成员必须使用注释,并描述清楚使用场景;
举例说明
/// <summary>
/// 表示使用的数据库引擎的选项;在程序启动时需要确定一个数据库使用引擎。
/// </summary>
public enum SqlEngines
{
/// <summary>
/// 表示不使用任何数据库引擎。
/// <para>若不使用任何数据库引擎,需要确保数据源不是来自于数据库,否则会抛出 <see sref="System.InvalidOperationException"/> 异常。</para>
/// </summary>
None = 0,
/// <summary>
/// 表示选择使用 SQL Server 作为数据库引擎。
/// <para>请确保传入的 T-SQL 语句是 SQL Server 可支持的,否则会抛出 <see sref="System.InvalidOperationException"/> 异常。</para>
/// </summary>
MSSQL = 1,
/// <summary>
/// 表示选择使用 MySql 作为数据库引擎。
/// <para>请确保传入的 T-SQL 语句是 MySql 可支持的,否则会抛出 <see sref="System.InvalidOperationException"/> 异常。</para>
/// </summary>
MySQL = 2
}
参数(argument)
- 必须使用 Camel 方式;
- 必须准确表达参数的意境,尽量使用名词;
- 不允许使用任何不被公认的单词缩写;
- 任何时候都必须对参数进行注释;
- 不允许使用下划线;
举例说明
- 正确
- void CreateFile(string fileName);
- void GetElementById(int id);
- 错误
- void CreateFile(string n, FileMode m);
- void GetElementByTagName(string tn);
- void GetElementByClass(string _className)
注释说明(summary)
- 必须说明该参数的用途;若有必要,请写明备注;
举例说明
/// <summary>
/// ...暂略
/// <param src="folderName">文件夹的名称。 如果传入 null,则系统将自动随机创建以 Guid 为标识的文件夹名称。</param>
/// </summary>
public void CreateFolder(string folderName)
方法(method)
- 必须使用 Pascal 方式;
- 使用动宾短语,一般以动词作为第一个单词,主要是表达这个方法需要做的事情,如:CreateFile;
- 不允许使用下划线和数字开头;
- 尽量不出现数字,可以在适当的时候以下划线作为单词分隔;
举例说明
- 正确
- public bool CreateFile(string fileName);
- public MyEntity GetEntityById(int entityId);
- public int ConvertToInt(string name);
- 错误
- public bool createFile(string name);
- public void Copy2Entity(MyEntity entity);
- private int _ToInt(string args);
方法注释(summary)
- 必须清晰表达该方法的目的和用途;
- 若有需要,必须写出在调用该方法所需要的注意事项;
- 若有需要,可以注明返回值的用途,并使用
<return>返回值用途</return>
标记说明; - 若有异常,必须将每一个异常使用
<exception sref="引发的异常类">异常出现的条件描述</exception>
标记说明;
举例说明
-
例1
/// <summary> /// 创建一个文件夹。若文件夹已经存在,则会抛出异常;请注意,传入的参数必须是一个完整的物理路径。 /// <param src="folderName">文件夹的名称。 如果传入 null,则系统将自动随机创建以 Guid 为标识的文件夹名称。</param> /// </summary> /// <exception sref="System.InvalidOperationException">同一个路径下的文件夹名称重复。</exception> public void CreateFolder(string folderName)
-
例2
/// <summary> /// 执行数据库的迁移操作。 如果在迁移队列中有任何等待迁移的数据,执行该方法后,会返回影响的行数;否则执行该方法将不会有任何结果,返回值为 0。 /// <para>如果你调用了该方法,则方法 DbMigrating 事件将会触发。</para> /// </summary> /// <return>如果成功迁移,返回迁移影响的行数;否则返回 0。</return> /// <exception src="System.InvalidOperationException">在迁移的过程中发生了错误,详细错误请参见 InnerException 属性。</exception> public int Migrate();
属性
- 必须采用 Pascal 方式;
- 必须是用名词,尽量不要太长;
- 不允许使用非国际公认的缩写;
- 不允许使用下划线;
- 不允许使用数字开头;
举例说明
- 正确
- public int OrderNo { get; set; }
- public string Name { get; set; }
- public string Name1 { get; set; }
- 错误
- public int orderno { get; set; }
- public string Name2Bill { get; set; }
- public string 2OnceMore { get; set; }
属性注释(summary)
- 如果属性有公开的 get,必须使用**“获取”**这个词;
- 如果属性有公开的 set,必须使用**“设置”**这个词;
- 如果以上都有,则使用**“或”**关键字连接;
举例说明
-
例1
/// <summary> /// 获取或设置用户的名称。 /// </summary> public string Name { get; set; }
-
例2
/// <summary> /// 获取用户的名称。 /// </summary> public string Name { get; private set; }
-
例3
/// <summary> /// 设置用户的名称。 /// </summary> public string Name { private get; set; }
不允许使用这种方式,应保证属性是至少是公开可读的,可声明一个 SetName() 方法代替
常量(consistant)
- 所有字母必须大写;
- 每一个单词必须使用**“下划线(_)”**分隔;
举例说明
- 正确
- const int PAGE_INDEX = 1;
- const string DEFAULT_NAME = “Default”;
- 错误
- const int page_index = 1;
- const string defaultName = “Default”;
常量注释(summary)
- 能表述该常量的用途和使用范围即可;
举例说明
/// <summary>
/// 表示当前分页的索引值。
/// </summary>
const int PAGE_INDEX = 1;
变量(variable)
- 必须使用 Camel 方式;
- 命名不允许使用任何无法表达其含义的词语;
- 不允许使用前缀,比如:m_index;
- 成员变量建议使用**“下划线(_)”**作为前缀,局部变量不允许这么做;
成员变量:作用域为整个类(class);局部变量:作用域在方法里或方法里其他代码块中的;
举例说明
- 正确
- UserService _userService; 成员变量可以
- int index;
- string userName;
- 错误
- UserService user_service;
- int _pageindex; 局部变量不可以
- string m_name;
变量注释(summary)
- 变量可以不强制写 summary 注释;
- 若需要,请尽量描述其用途;
特性(Attribute)
- 必须使用 Pascal 方式;
- 必须使用 “Attribute” 为后缀;
- 必须使用名词或名词短语作为名称;
- 不允许使用非国际公认简写;
- 不允许包含下划线和数字;
举例说明
- 正确
- NotMappingAttribute
- RequireAttribute
- 错误
- NotMapping
- _AppModule
- Build_In2
特性注释(summary)
- 必须将使用该特性的用途进行描述;
- 建议使用**“表示xxxxx”**这样的词语;
举例说明
/// <summary>
/// 表示不对当前的数据库字段进行映射操作;
/// </summary>
public class NotMappingAttribute : Attribute
异常(Exception)
- 必须采用 Pascal 方式;
- 必须以 “Exception” 作为后缀;
- 建议使用名词或短语命名;
- 不允许使用非国际公认简写;
- 不允许包含下划线和数字;
举例说明
- 正确
- DataNotFoundException;
- InvalidCastException;
- 错误
- _TryGoEast
- No2_FieldException
异常注释(summary)
- 建议使用 “尝试xxxxx引发的异常” 或 “当xxxxx时引发的异常” 这样的短语;
举例说明
/// <summary>
/// 当无法找到指定数据时引发的异常。
/// </summary>
public class DataNotFoundException : Exception
委托(Delegate)
- 必须使用 Pascal 方式;
- 必须使用 “Handler” 作为后缀;
- 建议使用名词或短语命名;
- 不允许使用非国际公认简写;
- 不允许包含下划线和数字;
举例说明
- 正确
- delegate void NameChangeHandler(string name);
- delegate int OperateAddHandler(int a, int b);
- 错误
- delegate void NameChange(string name);
- delegate int Operate_Add_Handler(int a, int b);
委托注释(summary)
- 建议使用 “当xxxx触发时处理的句柄” 这样的语句进行描述;
- 如果有参数,需要说明参数的用途;
- 如果有返回值,需要说明返回值的用途;
举例说明
/// <summary>
/// 当执行添加操作时的处理句柄。
/// </summary>
/// <param name="a">需要执行添加操作的值。</param>
/// <param name="b">需要执行添加操作的值。</param>
/// <return>添加操作成功执行后的返回结果。</return>
public delegate int AddHandler(int a, int b);
事件
- 必须采用 Pascal 方式;
- 必须使用 “On” 作为前缀;
- 必须使用动词进行式或过去分词的方式作为后缀,例如:OnNameChanging 或 OnNameChanged
- 不允许使用下划线和数字;
举例说明
- 正确
- public event ChangeNameHandler OnNameChaning;
- public event MoveFolderHandler OnFolderMoved;
- 错误
- public event ChangeNameHandler ChangeName;
- public event MoveFolderHandler On_Folder_Move2;
事件注释(summary)
- 如果是 ing 形式,可使用**“当xxxx时触发的事件”**的语句;
- 如果是过去分词,可使用**“当xxx后触发的事件”**的语句;
- 建议最好写明使用场景;
举例说明
/// <summary>
/// 当文件夹被移动时触发的事件。
/// </summary>
public event MoveFolderHandler OnFolderMoving;