NET设计规范二:类型成员设计
http://www.cnblogs.com/yangcaogui/archive/2012/04/20/2459567.html
接着 → .NET设计规范一:设计规范基础 上一篇,我们来了解下类型成员命名的设计!
3.类型成员命名的设计
3.1字段
①遵循“ camelCasing ”的命名规则
②要用名词或名词词组,不要使用C#关键字
③不要给字段添加任何前缀
④定义常量的时候要使用“PascalCasing ”的命名规范
⑤当定义私有变量的时候使用“camelCasing”命名,并且在前面加上“_”作为前缀
3.2方法
①必须为动词词组,不要使用C#关键字
②尽量根据方法对应的任务来命名,而不是根据内部一些实现细节来命名!
常用的动词有:Get,Update,Delete,Add,Validate,Select,Search等等,这些动词后面加上你要做的内容,就构成了一个个方法名!
3.3属性
①应该用名词或名词词组或形容词或形容词词组来命名,遵循“PascalCaing”大小写规范!
②不要让属性名与“Get”方法名相似
这种情况说明属性应该是方法,应该合二为一,只定义一个方法!
③要使用肯定性的短语,如:CanSeek,而不是CantSeek
③如果属性的返回值是“bool”值,可以考虑为属性名添加“Is”,“Can”,“Has”等前缀!
1 public bool CanSeek { get; set; }
2 public bool CantSeek { get; set; } //不推荐
3 public bool HasValue { get; set; }
不过这种情况视情况而定,如果加了前缀反而使名称变的冗长了,那么就不要添加前缀了!
3.4事件
推荐文章:C# 中的委托和事件
事件的设计个人认为是非常重要,所以我也很用心的学习了它.
基本命名规则:
①要用动词或动词词组来命名
如:Ckecked,Updated,Selected等等的动词或动词词组
②不要用“Before”或“After”等词语来表示前置事件或后置事件
③需要为事件定义一个参数信息实体,必须要以“EventArgs”后缀结尾
④要为绑定事件的方法名加上“On”前缀
定义事件的基本的框架如下:
1 public class DemoSeven
2 {
3 public event EventHandler<UpdatedEventArgs> Updated;
4 private UpdatedEventArgs _updatedEventArgs = new UpdatedEventArgs() { UpdatedID = "1234" };
5 private EventHandler<UpdatedEventArgs> _updatedHandler;
6
7 private const string str = "";
8 private readonly string strOne = "";
9
10 public void OnUpdated() //执行事件的方法
11 {
12 _updatedHandler = Updated;
13 if (_updatedHandler != null)
14 {
15 _updatedHandler(this, _updatedEventArgs);
16 }
17 }
18 }
19
20 public class UpdatedEventArgs : EventArgs //参数信息实体类
21 {
22 public string UpdatedID { get; set; }
23 }
3.5索引器
其实说明白点索引器就是对集合或数组的封装.
索引器的设计规则基本上都是固定的,都是使用“this”关键字的,如下:
1 public string this[int index]
2 {
3 get { return ""; }
4 }
5
6 public string this[int index, string name]
7 {
8 get { return ""; }
9 }
3.6资源的命名
可能在转换多国语言的时候会用到资源,那么资源里面参数的命名也变的很重要了!
①使用“PascalCasing ”命名方法,不要使用C#关键字
②要是名字具有描述性,而不是一味的把名字变短,当然也要保证名字的简短性,不过前提不能牺牲可读性
③尽量使用字母,数字和下划线
④要用点号来标识符清楚的划分层次
⑥对待异常信息要加上“Exception”的后缀
如果大家都知道,就当复习咯!
下一篇:.NET设计规范三:类型和类型成员设计的约定和惯用法
.NET设计规范三:类型和类型成员设计的约定和惯用法
继续上两篇未完成的工作 → ①.NET设计规范一:设计规范基础 ②.NET设计规范二:类型成员设计
上两篇主要是说了类型和类型成员在命名上的规范,对它们的具体设计还没有涉及到,这篇文章是从一个普通开发人员的角度理解,会有很多不足之处,希望能得到大家的指点!
首先说一下本文只是借助书本做的一些小结,大牛(架构师)们请不要喷我,如果实在憋不住,那就是使劲的喷吧,在喷中成长!
4.类型设计的约定和惯用法
4.1类和接口的选择
①应该优先使用类
首先类是用于暴露抽象的优先选择!
微软开发人员提供给我们的方案是:定义一个接口,然后再定义一个抽象基类实现这个接口!
1 public interface IComponent //这是.NET Framework中比较突出的案例
2 {
3 void GetID();
4 }
5
6 public class Component:IComponent
7 {
8 public void GetID()
9 {
10 // To Do.
11 }
12 }
②要用抽象类而不是接口来解除协定与实现之间的耦合
③如果需要定义一个多态的值类型层次结构的话,要定义一个接口
1 public struct Int32 : IComparable, IFormattable, IConvertible
2 {
3
4 }
5 public struct Int64 : IComparable, IFormattable, IConvertible
6 {
7
8 }
④考虑使用接口来实现多重继承
Note:定义一个接口的标志就是它只做一件事。
4.2抽象类的设计
优点:
①灵活性比较大
②能通过继承扩展功能
③可以对抽象类中的虚方法和抽象方法实现重写达到功能扩展
设计:
①抽象类中的构造函数修饰符因为为“protected”或者为“interal”,不过大多数情况都是“protected”
②定义好的抽象类必须要有类去继承它,而不能让它成为孤家寡人,这样有助于验证抽象类的有效性
1 public abstract class Animal
2 {
3 protected Animal()
4 {
5 }
6 }
4.3接口的设计
①接口可以支持多重继承
②避免使用记号接口(也就是无成员的接口)
③要为接口提供实现的类型,跟上面抽象类一样,不要成为孤家寡人
④在大型项目开发中,都会提供一系列的接口供外部调用(这也是设计接口的场景之一)
⑤接口一旦定义就不能做改动了
4.4静态类的设计
①尽量少自定义静态类,如果设计的静态类有一种辅助的效果,那么就应该定义一个这样的静态类,如.NET Framework中的“File”类,一种文辅助类
②不要在静态类中声明或覆盖实例成员
③要把静态类定义为密封的,抽象的,并添加一个私有的构造函数
4.5结构的设计
①不要为结构提供默认的构造函数
②一般来说自定义的结构类比较少
4.6枚举的设计
①要用枚举来加强那些表示值的集合的参数,属性或者返回值的类型型
②要优先使用枚举而不要使用静态变量
比如:在定义一些颜色属性的时候,使用枚举是最好的选择。
③不要提供为了今后使用的枚举值
④不要定义枚举中只有一个值,如果只有一个那还不如定一个常量呢!
⑤要为简单的枚举提供“0”值,详细理解“0”值请看 → 从枚举的初始化说起 [C#]
1 public enum Color
2 {
3 Red = 0, //这是一种规范
4 Yellow = 1,
5 Black = 2
6 }
⑥考虑用“Int32”类型数值作为枚举值的值
⑦要使用复数名词或名词词组命名“标记枚举”,用单数名词或名词词组命名简单枚举
4.7标记枚举
标记枚举提供对枚举值的位操作!
①必须要加上“[Flags]”标志特性
②要用2的幂次方作为标记枚举的值(其实这个规则不怎么明白,不过这确实是一个很重要的规范)
1 [Flags]
2 public enum MyEnumTypes
3 {
4 Created = 0x0002,
5 Updated = 0x0004,
6 Deleted = 0x0008
7 }
③在合适的情况下要为标记枚举提供特殊的枚举值,也就是组合枚举
1 [Flags]
2 public enum FileAccess
3 {
4 Read = 1, //这边定义的“int”型的枚举值跟上面使用2的幂次方作为枚举值没有冲突,我们应该在以后的开发中使用2的幂次方作为枚举值
5 ReadWrite = 3, //提供一个组合值,或者这样 → ReadWrite = Read | Write
6 Write = 2
7 }
④不要定义无效的枚举值
5.成员设计
5.1方法的重载
①避免在重载的时候随意给参数名,应该保持参数名的一致性
②避免打乱参数的顺序,在多个重载中保持参数顺序的一致性
③要把最长的重载做成“虚方法”,这样有助于派生类的重写,增强了扩展性
④不要在重载成员中使用“ref”或“out”参数
⑤要允许引用类型的参数可为“null”,不过需要在方法中对“null”值进行判断
5.2显式和隐式实现接口
①避免显式实现接口
感觉这个规范在“迭代器”中的运用还是比较多的,可以参照这篇文章:程序猿个人文章目录索引中的迭代器系列
说实话这个话题我也不敢讲多少,因为我自己对它本质的东西理解的好不够深入,所以就泛泛的说几句!
5.3属性和方法的选择
①属性侧重于数据的体现,而方法侧重于操作,不过话说两者的性能不是很多(虽然书上也讨论过两者性能差异,但是可以忽略不急)
②建议多使用属性,如果定义够多的属性,那么相应的就要为属性定义同等的私有变量,也就是对变量的封装
③避免方法中参数过多,如果太多建议使用属性来减少方法重载
④需要使用方法的一些通用情况
I,该操作是一个转化操作,如:ToString()方法
II,该操作每次返回的结果不一样,如:Guid.NewGuid()
III,该操作返回的是一个数组或集合(这个情况还是蛮实用的)
⑤所以说使用属性是它只代表简单的数据操作,过于复杂的操作应该使用方法来完成
5.4索引器的设计
个人理解:索引器就是对集合以及数组的封装!
索引器可以是单个索引也可以是多个索引,索引器是附加在类级别上的,所以它才使用“this”关键字的,在前面一文中也简单的介绍了这方面的知识!
①避免使用一个以上参数的索引器
5.5构造函数设计
有两种构造函数:类型构造函数和实例构造函数
类型构造 → 也就是静态构造函数,必须为静态的,在进行初始化的时候是第一个执行的!
①必须为私有构造(编译器会强制规定的)
②不要在类型构造中抛出异常
实例构造 → 也就是普通的构造
①考虑提供简单的构造函数,可以默认构造函数
②如果使用构造函数重载,那么构造函数的参数作用应该设置为主要属性,而不是“可有可无”的参数
③要在构造函数做最少的事
④如果要使用构造函数重载,需要提供一个空构造,这样就不会破坏依赖于空构造的类型成员
5.6事件的设计
关于事件定义的基本规范可以参考前一篇的文章!
①要使用系统自定义的委托 → EventHandler<T> (可以说这是个通用规范把)
②考虑把事件的处理方法设置为虚方法,这样派生类就可以重写,提高扩展性
如果想深入理解推荐几篇文章:C#委托和事件(2) ,浅谈C#中常见的委托,C# 中的委托和事件
5.7字段的设计
①不要提高公共的或受保护的实例字段
②要使用属性来访问字段,这样跟直接访问字段是一样的
③要用常量字段来表示永远不会改变的常量,大家可以找点资料理解下“const”和“readonly”的差异
④不要把可变类型的实例赋值给只读字段
⑤要用公有的静态只读字段来定义预定义的对象实例(这个个人理解起来有点不懂)
好了就写这么多了,感觉好累,因为本人不是啥架构师,是个小菜鸟(这是从我这个角度看问题的,高度还没有上升上去),写这些东西也是模仿书上的,算是一点小总结,不能算经验的!
如有问题还请大家多多指教!
下一篇:.NET设计规范四:简单的扩展设计与个人思考
.NET设计规范四:简单的扩展设计与个人思考
有一个星期没有写文章记录学习与工作之路了,今天趁着是五四青年节下午休息的时光写了.NET设计规范的最后一篇了!
在做好一系列的命名规范,设计规范之后,更高层的规范就是那些扩展性的规范了(或者说是面向对象,其实这方面我是菜菜鸟),这里我只简单的说说!
说实话写这样的文章真不好写,尤其是涉及到架构方面的设计我更是无从下手,所以我就把书本上的总结一下,尽量少一点个人想法!
接着上三篇:①.NET设计规范一:设计规范基础 ②.NET设计规范二:类型成员设计 ③.NET设计规范三:类型和类型成员设计的约定和惯用法
5.扩展性设计
5.1密封类
①不推荐使用密封类,除非有特殊的理由
5.2抽象类和抽象接口
①必要的时候应该定义一个抽象类(或者是一个基类)和一个接口,然后用抽象类(或基类)实现这个接口
5.3基类
6.异常的设计
6.1自定义异常的设计
①避免太深的继承层次
②必须要从“System.Exception”派生出新的异常类,这是个规范
③要在异常类名称后面加上“Exception”后缀
④要是的异常可以序列化,这是为了能够跨应用程序和跨平台
⑤要为异常提供常用的构造函数
⑥要定义“ToString”方法返回异常信息
⑦书中的两点建议,不怎么明白
1 [Serializable]
2 public class MyException:Exception //这是最简单的异常处理信息
3 {
4 private string _message;
5
6 public MyException()
7 {}
8 public MyException(string message)
9 {
10 _message = message;
11 }
12
13 public override string ToString()
14 {
15 // TO DO.
16 return "";
17 }
18 }
PS:书中对异常的介绍写了很多,可是理解的很少,这里就把自己的理解写了下来,所以还需要在看几遍,这样才能慢慢的理解他!
7.数组,特性,集合的编码规范
7.1数组
①优先使用集合而不是数组
②不要把数组设计为只读数组,应该使得用户可以修改数组中的元素
7.2Attribute(特性)
①命名时要添加“Attribute”后缀,并且继承“Attribute”基类
public class MyAttribute:Attribute
②要在自定义的时候使用“AttributeUsageAttribute”这个特性
1 [AttributeUsage(AttributeTargets.All)]
2 public class MyAttribute : Attribute
3 {
4
5 }
③要为可选参数提供可设置的属性
④要为必填参数提供只读属性
⑤要提供构造函数对必填参数进行初始化,每个参数名应该与相应的属性名一样(可能大小写会不一样)
1 [AttributeUsage(AttributeTargets.All)]
2 public class MyAttribute : Attribute
3 {
4 public MyAttribute(string name, string message)
5 {
6 Name = name;
7 Message = message;
8 }
9
10 private string Name { get; set; } //这是必填参数
11 private string Message { get; set; } //这是必填参数
12 public string Author { get; set; } //这是可选参数
13 }
14
15 [My("ss", "ss", Author = "sss")] //那么我在调用时就会出现如下调用方式
16 public class One
17 { }
⑤尽可能把自定义的Attribute密封起来,这样会是的查找“Attribute”更快
⑥避免提供构造函数对可选参数进行初始化
⑦避免对自定义的“Attribute”构造函数进行重载
7.3关于集合属性和返回值
①不要提供可设置的集合属性
1 public Collection<String> Items { get; set; } //坏的设计
2 public Collection<string> Items //提倡的设计
3 {
4 get
5 {
6 // TO DO
7 }
8 }
②要用“Collection<T>”或其子类作为属性或返回值来表示可读写的集合(就像上面一样)
③使用“ReadOnlyCollection<T>”作为属性或返回值来表示只读集合
这篇文章写的不好,可能真的是由于本人知识积累的有限,写的很艰难,不过最终还是写好了,继续加油把!
NET设计规范二:类型成员设计的更多相关文章
- 《.NET 设计规范》第 5 章:成员设计
<.NET 设计规范>第 5 章:成员设计 5.1 成员设计的通用规范 要尽量用描述性的参数名来说明在较短的重载中使用的默认值. 避免在重载中随意地改变参数的名字.如果两个重载中的某个参数 ...
- F2工作流引擎参与者类型成员的交、并、互拆计算规则
计算描述:计算规则指的是和其它“参与者类型成员”的之间的计算,必须求解处理人不为空的情况下才进行规则计算,各个“参与者类型成员”按序号顺序执行. 计算算法:并集(权重最低),交集(权重中) ...
- NET设计规范(二) 命名规范
http://blog.csdn.net/richnaly/article/details/6280294 第2章 命名规范 2.1. 大小写约定 2.1.1. 标识符的大小写规 ...
- C#成员设计建议
所谓成员,是指类型的字段和方法.在成员设计时,掌握一定原则可以避免设计上的陷阱. 1.不要为抽象类提供公开的构造方法 抽象类可以有构造方法,但是抽象类不能实例化.如果编程人员没有制定构造方法,编译器会 ...
- 【.net 深呼吸】细说CodeDom(5):类型成员
前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...
- SAP CRM 用户界面对象类型和设计对象
在CRM中的用户界面对象类型的帮助下,我们可以做这些工作: 进行不同的视图配置 创建动态导航 从设计层控制字段标签.值帮助 控制BOL对象的属性的可视性 从导航栏访问自定义组件 一个用户界面对象类型之 ...
- 实验一《开发环境的熟悉》&实验二《固件设计》
20145312&20145338 实验一<开发环境的熟悉>&实验二<固件设计> 合作博客链接:http://www.cnblogs.com/yx2014531 ...
- python3.4学习笔记(二) 类型判断,异常处理,终止程序
python3.4学习笔记(二) 类型判断,异常处理,终止程序,实例代码: #idle中按F5可以运行代码 #引入外部模块 import xxx #random模块,randint(开始数,结束数) ...
- 收集整理Android开发所需的Android SDK、开发中用到的工具、Android开发教程、Android设计规范,免费的设计素材等。
AndroidDevTools Android Dev Tools官网地址:www.androiddevtools.cn 收集整理Android开发所需的Android SDK.开发中用到的工具.An ...
随机推荐
- noip2007树网的核
想一下可以发现随便枚举一条直径做就可以了. 核越长越好.于是枚举核的过程可以做到O(n) 然后就是统计答案. 对于每个核最大偏心距肯定是核上面每个点不走核内的点所能走到的最远点的最值. 而且对于核的两 ...
- POJ 2378 Tree Cutting 3140 Contestants Division (简单树形dp)
POJ 2378 Tree Cutting:题意 求删除哪些单点后产生的森林中的每一棵树的大小都小于等于原树大小的一半 #include<cstdio> #include<cstri ...
- python3-开发进阶Flask的基础(4)
今日内容: 上下文管理:LocalProxy对象 上下文管理: 请求上下文: request/session app上下文:app/g 第三方组件:wtforms 1.使用 ...
- bzoj 1086 树分块
将树分成一些块,做法见vfleaking博客. /************************************************************** Problem: 108 ...
- bzoj 2733: [HNOI2012]永无乡 -- 线段树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自 ...
- BFS洪水
试题描述: 已经连续下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY所在的城市可以用一个N*M(N,M<=50)的地图 ...
- js 运算符 || && 妙用
首先出个题:如图: 假设对成长速度显示规定如下: 成长速度为5显示1个箭头: 成长速度为10显示2个箭头: 成长速度为12显示3个箭头: 成长速度为15显示4个箭头: 其他都显示都显示0个箭 ...
- c# -- Form1_Load()不被执行的三个解决方法
我的第一个c#练习程序,果然又出现问题了...在Form1_Load() not work.估计我的人品又出现问题了. 下面实现的功能很简单,就是声明一个label1然后,把它初始化赋值为hello, ...
- Python可执行对象——exec、eval、compile
Python提供的调用可执行对象的内建函数进行说明,涉及exec.eval.compile三个函数.exec语句用来执行存储在代码对象.字符串.文件中的Python语句,eval语句用来 ...
- U-Boot中的filesize环境变量
U-Boot中的环境命令可以使用$(filesize)来确定刚下载(传输)得到的文件大小. 因为使用类似tftp命令传输文件后,会自动更新filesize环境变量.如:setenv updateroo ...