《框架设计指南》介绍了设计框架的最佳实践,依循本书设计出的框架是可复用的面向对象库。书中的准则适用于各种规模和尺度的复用,包括:

  • 大型系统框架,比如.NET的核心库,通常包含上千种类型,并被数以百万的开发者所使用。
  • 大型分布式应用中中等规模的可复用层或系统框架的扩展,如Azure SDK,游戏引擎等。
  • 多个应用程序之间的共享小组件,如栅格控件。

  需要注意的是,本书关注是那些直接影响框架(公开可访问的API——其包含公开可访问的类型声明,以及这些类型的公开的(public)、受保护的(protected)和显示实现的成员)可编程性的设计问题。所以,本书中通常不会包含太多实现的细节。就像一本用户界面设计的书不会详细介绍如何是心啊命中测试(可视化层中的命中测试 - WPF .NET Framework | Microsoft Learn)一样,本书也不会介绍如何实现二分排序。在该范围内,我们能够为框架设计者提供明确的指导,而不是将其变成另外一本关于编程的书。本书假定读者已经对.NET编程有了基本的了解。

  这些准则始于.NET框架开发的初期,它们最初只是一个小组关于命名和设计的约定,但是经过不断地增强、审核和改进,在微软内部,它们已经被当作框架设计地规范。在.NET过去地20年里,它们累积了成千上万名开发者地经验与智慧。我们试图避免将本书建立在理想主义地设计哲学之上,同时我们认为,微软开发团队对本书地日常使用,也使其成为一本极具实用价值的书。

  本书包含了许多注解,这些注解或者解释了准则中的权衡,或者描述了相关经历,或者扩展了准则,又或者提供了对准则的批评意见。这些注解是由经验丰富的框架设计者、行业专家和资深用户所编写的。来自一线的故事可以为诸多准则增光添彩。

  为了使命名空间、名称、类、接口、方法、属性和类型在文中更容易被区分,我们使用等宽字体来标识它们。

  准则呈现说明

  我们通过DOCONSIDERAVOIDDON'T把这些准则组织成简单的建议,每条准则都描述了正确的或糟糕的实践,并且都有一致的表述。在正确的实践前面会有一个√,在糟糕的实践前面会有一个×。每条准则的措辞也会表明建议的程度。例如,由DO引导的准则应该总是(“总是”这个词的语气获取太强烈了。有一些准则使应该严格遵循的,但是它们极其罕见。相比之下,要打破由DO引导的准则,你需要找出特殊的实例,并且确保对它框架的用户来说是有益的。)被遵循的(本书中所有的例子):

  ✔DO要以“Attribute”后缀来命名的自定义特性类。

public class ObsoleteAttribute:Attribute{...}

  通常来说,由CONSIDER引导的准则都是应该被遵循的,但是如果你完全理解一条准则背后的原因,并且由充分的理由不去遵循它,那么你就无须为违反这条准则而感到不安。

  √CONSIDER 当类型的实例很小且通常存活时间很短,或者通常被嵌入其他对象中时,应该考虑使用结构体,而不是使用类。

  同样地,由DON'T引导地准则则指出那些你几乎永远不应该做地事情。

  ×DON'T不要提供只写属性,或者使setter拥有比getter更宽松的可访问性。

  相比而言,由AVOID引导的准则则禁止的语气更弱一些,这些准则在绝大多数情况下都使用,但是在一些已知的情况下,被打破也是合理的。

  ×AVOID 如果只是想使用Count属性,则应避免将ICollection<T>或ICollection作为参数类型。

  一些更为复杂的准则后面会紧跟着额外的背景信息、解释性代码示例或基本原理。

  √DO要为值类型实现IEquatable<T>。

  值类型的Object.Equals方法会导致装箱,因为它的默认实现用到了反射,所以效率不高。IEquatable<T>.Equals可以提供更好的性能,你可以选择使用不会导致装箱的方式来实现它。

public struct Int32:Equatable<Int32>{
  public bool Equals(Int32 other){...}  
}

  语言选择和代码示例

  通用语言运行时(CLR)的一个目标是支持不同的编程语言:不仅包括那些由微软可实现的编程语言,如C++、VB、C#、F#、IronPython、PowerShell等,还包括那些由第三方提供支持的语言,如Eiffel、COBOL、Fortan等。因此,对于许多可用来开发或使用现代框架的编程语言来说,本书均适用。

  为了强化多语言框架设计这一信息,我们考率过使用几种不同的编程语言来编写代码示例,但最后决定不这样做。我们觉得,虽然使用不同的语言有助于传达本书的设计哲学,但是其可能会迫使读者去学习几种新的语言,这不是本书的目的。

  我们决定使用一种对广大开发人员来说相对易读的语言,所以选择了C#。因为C#是来自C语言家族(C、C++、Java和C#)的语言,这个家族在框架开发中有着深厚的历史底蕴。

  对于很多开发人员来说,语言选择非常重要,我们在这里向那些不满于我们的选择的读者致以歉意。

  关于本书

  本书为框架设计提供了自上而下的指南。

  第1章,”导论“,介绍了本书的简要定位,描述了框架设计的一般理念。这是书中唯一没有准则的章节。

  第2章,”框架设计基础“,提供了整体框架设计中最基本的原则和准则。

  第3章,”命名准则“,包含了框架中许多方面通用的设计惯例和命名准则,比如命名空间、类型和成员。

  第4章,”类型设计准则“,为类型的一般设计提供了指导。

  第5章,”成员设计“,更进一步地介绍了类型成员地设计准则。

  第6章,”可扩展性设计“,所介绍地问题和准则对确保框架的适当可扩展性十分重要。

  第7章,”异常“,介绍了与异常处理相关的准则,以及首选的错误报告机制。

  第8章,”使用准则“,包含了如何扩展及使用框架中常见类型的准则。

  第9章,”通用设计模式“,提供了常见框架设计模式中所涉及的准则和相关代码示例。

  附录A,”C#编码风格约定“,描述了在.NET中生成和维护核心库的团队所使用的编码约定。

  附录B,”过时的准则“,包含了在本书之前的版本中出现过,而本书不再推荐的应用于特定特性或概念的准则。

  附录C,”API规范示例“,这是微软的框架设计师在设计API时所创建的API规范的部分示例。

  附录D,”不兼容变更“,探索了各种可能会对用户产生负面影响的变更。