MyException - 我的异常网
当前位置:我的异常网» 编程 » 第3章 部类设计规范

第3章 部类设计规范

www.MyException.Cn  网友分享于:2013-10-09  浏览:3次
第3章 类型设计规范

ü 要确保每个类型由一组定义明确、相互关联的成员组成。

3.1. 类型和名字空间

ü 要用命名空间把类型组织成一个相关的特性域的层次结构。

 

û 避免非常深的名字空间层次。这样的层次难于浏览,因为用户不得不经常地回溯。

 

û 避免有太多的名字空间。

 

û 避免把为高级场景而设计的类型和为常见编程任务而设计的类型放在同一个名字空间中。

 

û 不要不指定名字空间就定义类型。

3.2. 类和结构之间的选择

ü 要深入了解引用类型和值类型在行为上的差异。

 

ü 作为一条经验法则,框架中的大多数类型应该是类。但是在有些情况下,由于值类型所具备的特征,使用结构会更为合适。

 

ü如果该类型的实例比较小而且生命期比较短,或者经常被内嵌在其他对象中,考虑定义结构而不要定义类。

 

û 不要定义结构,除非该类型具有以下所有特征:

Ø 它在逻辑上代表一个独立的值,与基本类型(intdouble等等)相似。

Ø 它的实例的大小小于16个字节。

Ø 它是不可变的。

Ø 它不需要经常被装箱。

在所有其他情况下,应该将类型定义为类。

3.3. 类和接口之间的选择

ü 要优先采用类而不是接口。

说明:与基于接口的API相比,基于类的API容易演化得多,因为可以给类添加成员而不会破坏已有的代码。

 

ü 要用抽象类而不是用接口来解除协定与实现之间的耦合。

说明:抽象类经过正确的设计,同样能够解除协定与实现之间的耦合,与接口所能达到的程度不相上下。

 

ü 如果需要提供一个多态的值类型层次结构的话,要定义接口。

说明:值类型不能来自其他类型继承,但它们可以实现接口。例如,IComparableIFormat table以及IConvertible都是接口,因此Int32Int64等值类型及其他基本类型,都可以是

comparableformattableconvertible的。

public struct Int32 : IComparableIFormattableIConvertible{}

public struct Int64 : IComparableIFormattableIConvertible{}

 

ü 考虑通过定义接口来达到与多重继承相类似的效果。

3.4. 抽象类的设计

û 不要在抽象类型中定义公有的或内部受保护的( protected-internal)构造函数。

说明:

只有当用户需要创建一个类型的实例时,该类型的构造函数才应该是公有的。由于你

无法创建一个抽象类型的实例,因此如果抽象类型具有公有构造函数,那么这样的设

计不仅是不当的,而且还会误导用户。

// bad design

public abstract class Claim

{

public Claim(int number){}

}

// good design

public abstract class Claim

{

// incorrect Design

protected Claim(int number){}

}

 

ü 要为抽象类定义受保护的构造函数或内部构造函数。

说明:受保护的构造函数更为常见,它仅仅是允许当子类型被创建时,基类能够做自己的初始化。

public abstract class Claim

{

protected Claim() { }

}

内部构造函数可以用来把该抽象类的具体实现限制在定义该抽象类的程序集中。

public abstract class Claim

{

internal Claim() { }

}

 

ü 要为你发布的抽象类提供至少一个继承自该类的具体类型。

说明:这有助于验证该抽象类的设计是否正确。例如,System.IOFileStreamSystem.IOStream抽象类的一个实现。

3.5. 静态类的设计

ü 要尽量少用静态类。

 

û 不要把静态类当做杂物箱。每一个静态类都应该有其明确的目的。

 

û 不要在静态类中声明或覆盖实例成员。

 

ü 要把静态类定义为密封的、抽象的,并添加一个私有的实例构造函数——如果你的编程语言没有内置对静态类的支持。

3.6. 接口的设计

ü 要定义接口,如果你需要包括值类型在内的一组类型支持一些公共的API

 

ü 考虑定义接口,如果你需要让已经自其他类型继承的类型支持该接口提供的功能。

 

û 避免使用记号接口(没有成员的接口)。如果你需要给一个具备某特征(记号)的类做记号,一般来说,最好使用自定义attribute而不要使用接口。

 

ü 要为接口提供至少—个实现该接口的类型。

例如:这有助于验证接口的设计。例如,System.Collections.ArrayListSystem.Collections.IList接口的一个实现。

 

ü 要为你定义的每个接口提供至少一个使用该接口的API(一个以该接口为参数的方法,或是一个类型为该接口的属性)。这有助于有助于验证接口的设计。

例如:List<T>.Sort使用了IComparer<T>接口。

 

û 不要给已经发行的接口再添加成员。

说明:这样做会破坏该接口的实现。为了避免版本的问题,应该创建一个新的接口。

3.7. 结构的设计

û 不要为结构提供默认的构造函数。

 

ü 要确保当所有的实例数据都为零、falsenull(如果合适)时,结构仍处于有效状态。这可以防止在创建一个结构的数组时创建出无效的实例。

例如:下面的结构设计得不正确。带参数的构造函数有意用来确保状态有效,但是在创建该结构的数组时,这个构造函数没有被执行,因此所有的实例字段都被初始化为0,而对该类型来说这并不是一个有效的状态。

//bad Design

public struct PositiveInteger

{

int value;

public PositiveInteger(int value)

{

if (value <= 0)

throw new ArgumentException(); }

this.value = value;

}

public override string ToString()

{

return value.ToString();

}

}

 

通过确保默认的状态(本例中的value宇段为0)是该类型的有效逻辑状态,这个问题

可以得到解决。

//good Design

public struct PositiveInteger

{

int value;

public PositiveInteger(int value)

{

if (value <= 0)

throw new ArgumentException(); }

this.value = value - 1;

}

public override string ToString()

{

return (value + 1).ToString();

}

}

 

ü 要为值类型实现IEquatable<T>

说明:值类型的ObjectEquals方法会导致装箱,而且它的默认实现也并不非常高效,因为它使用了反射。IEquatable<T>Equals的性能要好得多,而且能够实现为不会导致装箱。

 

û 不要显式地扩展System.ValueType,事实上大多数编程语言不允许这样做。

3.8. 枚举的设计

ü 要用枚举来加强那些表示值的集合的参数、属性以及返回值的类型性。

 

ü 要有限使用枚举而不要使用静态常量。

//Avoid the following

public static class Color

{

public static int Red = 0;

public static int Green = 1;

public static int Blue = 2;

}

//Favor the following

public enum Color

{

Red,

Grean,

Blue

}

 

û 不要把枚举用于开放的集合(比如操作系统的版本、朋友的名字等)

 

û 不要提供为了今后使用而保留的枚举值。

 

û 避免显式暴露只有一个值的枚举。

 

û 不要把sentinel值包含在枚举值中。

例如,下面的代码显示了一个带sentinel值的枚举,这个附加的sentinel值用来表示枚举的最后一个值,其目的是用于范围检查。在框架设计中,这是不好的做法。

public enum DeskType

{

Circular = 1,

Oblong = 2,

Rectangular = 3,

LastValue = 3 //this sentinel should not be here

}

 

public void OrderDesk(DeskType desk)

{

if (desk > DeskType.LastValue)

throw new ArgumentOutOfRangeException(); }

}

 

ü 框架的开发人员应该用真实的枚举值来执行检查,而不应该依赖于sentinel值。

public void OrderDesk(DeskType desk)

{

if (desk > DeskType.Rectangular||desk<DeskType.Circular)

throw new ArgumentOutOfRangeException(); }

}

 

ü 要为简单枚举类型提供零值。

例如:可以考虑把该值称为“None”之类的东西。如果这样的值不适用于某个特定的枚举那么应该把该枚举中最常用的默认值赋值为零。

public enum Compression

{

None = 0,

GZip,

Deflate

}

public enum EventType

{

Error = 0,

Warning,

Information

}

 

ü 考虑用Int32(大多数编程语言的默认选择)作为枚举的基本实现类型,除非下面的

任何一条成立:

Ø 该枚举是一个标记枚举,而你有超过32个标记,或预计今后会有更多的标记。

Ø 为了更方便地与需要不同大小的枚举的非托管代码进行互操作,基本的实现类型必须是Int32之外的类型。

Ø 更小的底层实现类型可能会节省相当的空间。

 

ü 要用复数名词或名词短语来命名标记枚举,用单数名词或名词短语来命名简单枚举。

 

û 不要直接扩充System.Enum

说明:SystemEnurn是一个特殊的类型,被CLR用来创建用户定义的枚举。大多数编程语言提供了相应的编程元素让你访问这项功能。例如,在C#中,enum关键字被用来定义一个枚举。

3.8.1. 标记枚举的设计

ü 要对标记枚举使用System.FlagsAttribute。不要把该attribute用于简单枚举。

[Flags]

public enum AttributeTargets

{ }

 

ü 要用2的幂次方作为标记枚举的值,这样就可以通过按位或操作自由地组合它们。

[Flags]

public enum WatcherChangeTypes

{

Created = 0x0002,

Deleted = 0x0004,

Changed = 0x0008,

}

 

文章评论

程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员的鄙视链
程序员的鄙视链
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
程序员和编码员之间的区别
程序员和编码员之间的区别
程序员都该阅读的书
程序员都该阅读的书
 程序员的样子
程序员的样子
鲜为人知的编程真相
鲜为人知的编程真相
总结2014中国互联网十大段子
总结2014中国互联网十大段子
漫画:程序员的工作
漫画:程序员的工作
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
那些争议最大的编程观点
那些争议最大的编程观点
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
旅行,写作,编程
旅行,写作,编程
代码女神横空出世
代码女神横空出世
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
老程序员的下场
老程序员的下场
编程语言是女人
编程语言是女人
中美印日四国程序员比较
中美印日四国程序员比较
每天工作4小时的程序员
每天工作4小时的程序员
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
我的丈夫是个程序员
我的丈夫是个程序员
10个调试和排错的小建议
10个调试和排错的小建议
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
我是如何打败拖延症的
我是如何打败拖延症的
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员必看的十大电影
程序员必看的十大电影
一个程序员的时间管理
一个程序员的时间管理
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
为什么程序员都是夜猫子
为什么程序员都是夜猫子
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
Java程序员必看电影
Java程序员必看电影
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有