`
t641339564
  • 浏览: 26409 次
  • 性别: Icon_minigender_1
  • 来自: 贵阳
社区版块
存档分类
最新评论

第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,

}

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    1数据库设计规范.doc

    数据库设计规范 [v1.0] 目 录 第1章 目的 3 第2章 设计规范 3 2.1 规范约定 3 2.2 字段规范 3 第3章 使用规范 3 3.1 综合 3 3.2 查询 5 3.3 增加 5 3.4 删除 5 3.5 修改 5 第4章 其它说明 5 目的 为了优化数据库的...

    .NET设计规范:约定、惯用法与模式(第2版)克瓦林纳 3/5

    第4章 类型设计规范  4.1 类型和名字空间  4.2 类和结构之间的选择  4.3 类和接口之间的选择  4.4 抽象类的设计  4.5 静态类的设计  4.6 接口的设计  4.7 结构的设计  4.8 枚举的设计  4.8.1 标记枚举的...

    .NET设计规范:约定、惯用法与模式(第2版)克瓦林纳 4/5

    第4章 类型设计规范  4.1 类型和名字空间  4.2 类和结构之间的选择  4.3 类和接口之间的选择  4.4 抽象类的设计  4.5 静态类的设计  4.6 接口的设计  4.7 结构的设计  4.8 枚举的设计  4.8.1 标记枚举的...

    .NET设计规范:约定、惯用法与模式(第2版)1/5

    第4章 类型设计规范  4.1 类型和名字空间  4.2 类和结构之间的选择  4.3 类和接口之间的选择  4.4 抽象类的设计  4.5 静态类的设计  4.6 接口的设计  4.7 结构的设计  4.8 枚举的设计  4.8.1 标记枚举的...

    .NET设计规范约定 惯用法与模式

    第4章 类型设计规范  4.1 类型和名字空间  4.2 类和结构之间的选择  4.3 类和接口之间的选择  4.4 抽象类的设计  4.5 静态类的设计  4.6 接口的设计  4.7 结构的设计  4.8 枚举的设计  4.8.1 标记...

    .NET设计规范:约定、惯用法与模式(第2版)克瓦林纳 2/5

    第4章 类型设计规范  4.1 类型和名字空间  4.2 类和结构之间的选择  4.3 类和接口之间的选择  4.4 抽象类的设计  4.5 静态类的设计  4.6 接口的设计  4.7 结构的设计  4.8 枚举的设计  4.8.1 标记枚举的...

    静电放电防护设计规范和指南

    第三章 静电放电的危害 5 3.1 ESD造成元器件失效 5 3.2 ESD引起信息出错,导致设备故障 5 3.3 高压静电吸附尘埃微粒 6 第四章 ESD防护设计指南 6 4.1 设备的ESD防护设计要求 6 4.2 PCB的ESD防护设计要求 7 4.3 通讯...

    .NET设计规范:约定、惯用法与模式(第2版)克瓦林纳 5/5

    第4章 类型设计规范  4.1 类型和名字空间  4.2 类和结构之间的选择  4.3 类和接口之间的选择  4.4 抽象类的设计  4.5 静态类的设计  4.6 接口的设计  4.7 结构的设计  4.8 枚举的设计  4.8.1 标记枚举的...

    NET设计规范-.NET约定、惯用法与模式.part2

    第4章 类型设计规范 60 4.1 类型和名字空间 62 4.2 类和结构之间的选择 67 4.3 类和接口之间的选择 69 4.4 抽象类的设计 76 4.5 静态类的设计 78 4.6 接口的设计 79 4.7 结构的设计 81 4.8 枚举的...

    NET设计规范-.NET约定、惯用法与模式.part1

    第4章 类型设计规范 60 4.1 类型和名字空间 62 4.2 类和结构之间的选择 67 4.3 类和接口之间的选择 69 4.4 抽象类的设计 76 4.5 静态类的设计 78 4.6 接口的设计 79 4.7 结构的设计 81 4.8 枚举的...

    Java高级程序设计实战教程第一章-Java编码规范.pptx

    1.2 相关知识 1.2.1 文件后缀名 1.2.2 源文件样式约定 1.2.3 注释规范 1.2.4 命名规范 Java高级程序设计实战教程第一章-Java编码规范全文共13页,当前为第3页。 1.2.1 文件后缀名 表1-1 Java程序使用的文件后缀名 ...

    C++ Qt设计模式(第2版)

    第3章 Qt简介 78 第4章 列表 85 第5章 函数 94 第6章 继承与多态 116 第7章 库与设计模式 163 第8章 QObject, QApplication,信号和槽 179 第9章 窗件和设计师 195 第10章 主窗口和动作 225 第11章 范型和...

    毕业设计工作规范及指导书 .doc

    第三章 毕业设计(论文)过程管理 27 3.1 毕业设计流程 27 3.2 毕业设计过程管理 27 3.3 毕业设计注意事项 29 3.4 毕业设计成绩汇总、总结上报 29 3.5 附录 29 附录一 丽水学院计算机与信息工程学院毕业设计学生自...

    程序设计方法学讲义(doc)

    第三章 程序的正确性证明 1、 程序的测试 2、 Floyd-Hoare规则公理方法 3、 Dijkstra最弱前置条件方法 第四章 数据类型与抽象 1、 类型概念 2、 数据类型 3、 数据抽象及其代数规范 4、 大型程序设计与抽象数据类型 ...

    C语言程序设计题库 第二章:数据类型、运算符和表达式

    三、当系统定义short int与int占内存长度相同,则两种类型常量均可以赋给 int和short int型变量。四、在整型常量后面加大写L或小写l,则告诉编译器,把该整型常量作为long类型处理。例:123L、0L。五、在整型常量...

    Python基础教程第2章.pptx

    第2章 Python语言基础 课程描述 本章将介绍Python语言的基本语法和编码规范,并重点讲解Python语言的数据类型、运算符、常量、变量、表达式和常用语句等基础知识,为使用Python开发应用程序奠定基础。 第2页,共133...

    Python程序设计教程-第02章-Python的基础知识.pptx

    第2章 Python的基础知识 Python程序设计教程-第02章-Python的基础知识全文共22页,当前为第1页。 内容简介 本章教学目标: 了解Python语言的书写规范; 明白Python标识符的命名规则; 掌握Python的基本数据类型与...

    程序设计方法学资料,国防工业出版社

    第3章 模块化程序设计 第1节 MODULA-2语言中的模块化结构 第2节 ADA语言中的程序包 习题 第4章 面向对象的程序设计方法 第1节 什么是面向对象的程序设计 第2节 应用框架 第3节 设计模式 第4节 浅谈面向对象设计语言 ...

    Python基础教程第2章(共133张).pptx

    第2章 Python语言(yǔyán)基础 课程描述 本章将介绍Python语言的基本语法和编码规范,并重点讲解Python语言的数据类型、运算符、常量、变量、表达式和常用语句等基础知识,为使用Python开发应用程序奠定基础。...

    亮剑.NET深入体验与实战精要.part3

     第3章 asp.net开发大杂烩  3.1 页面生命周期  3.2 页面状态管理  ……  第4章 windows窗体编程你也行  第5章 数据库开发  第6章 关于xml  第7章 web service开发详解  第8章 用户体验的杀手锏——...

Global site tag (gtag.js) - Google Analytics