2018正版葡京赌侠诗《.NET 设计规范》第 9 章:常用的设计形式

第 9 章:常用的设计格局

9.1 聚合组件

  考虑为常用的特性域提供聚合组件。

  要用聚合组件来对高层的定义(物理对象)进行建立模型,而不是对系统级的职务展开建立模型。

  要让聚合组件的名字与肯定的系统实体相对应,比如
MessageQueue、Process 或 伊芙ntLog,这样就能使项目特别显然。

  要在筹划聚合组件时使发轫化尽或者地大约,那样用户只需实行简易的开端化就足以选用组件。倘若某一项开首化是不可或缺的,那么由于并未对组件实行开头化而吸引的老大应该显然地告知用户应该如何做。

  不要供给聚合组件的用户在三个光景中显式地实例化多个指标。

  要保管让聚合组件帮助 Create-Set-Call
使用情势,那样用户就可以先实例化组件,然后设置它的质量,最后调用一些简单的艺术,以贯彻多数场合。

  要为全数的集聚组件提供私下认可构造函数或卓殊简单的构造函数。

  要为聚合组件提供可读写的习性来与构造函数中的全部参数相呼应。

  要在集结组件中运用事件,不要选择基于委托的 API。

  考虑用事件来代表须求被覆盖的虚成员。

  不要须求聚合组件的用户在常用场景中使用持续、覆盖方式及完毕接口。

  不要供给聚合组件的用户在常用场景中除了编写代码之外,还要做任何的做工。例如,不该让用户用配备文件来配置组件,也不应有让用户生成财富文件,等等。

  考虑让聚合组件能够自动切换状态。

  不要涉及有八种景况的因数类型。

  考虑将集纳组件集成到 VS 的设计器中。

  考虑把聚合组件和因子类型分开,各自放在不一样的主次集中。

  考虑把聚合组件内部的因数类型暴光给外界访问。

 

9.2 Async 模式

  要促成基于事件的 Async 格局 –
假若类型是三个帮助可视化设计器的零部件(也正是说类型达成了 IComponent)。

  要兑现经典的 Async 方式 – 借使非得辅助等待句柄。

  考虑在贯彻高层 API 时使用基于事件的 Async
形式。例如,聚合组件就活该完毕该形式。

  考虑在贯彻底层 API 时使用经典的 Async
格局,在那种景观下更强劲的遵循、更少的内部存款和储蓄器消耗、更好的油滑、更少的磁盘占用要比可用性更器重。

  幸免在同一个种类中竟然是一组有关的档次中而且落到实处二种 Async 方式。

  要在为异步操作定义 API 时遵守下边包车型地铁预订。给定名为 Operation
的共同方法,应该提供名为 BeginOperation 和 EndOperation
的不二法门,它们的情势签名如下边所示(注意,输出参数不是必备的)。

  要确认保障 Begin 方法的回到类型达成了 IAsyncResult 接口。

  要保管同步方法的按值传递和按引用传递的参数在 Begin
方法中都是按值传递的。同步方法的输出参数不应有出现在 Begin
方法的签订契约中。

  要确认保证 End 方法的回到类型与一起方法的归来类型相同。

  要保障同步方法的别样输出参数和按引用传递的参数都看作 End
方法的出口参数。同步方法中安放传递的参数不应该出现在 End 方法的签名中。

  不要继续执行异步操作 – 若是 Begin 方法抛出了充裕。

  要三遍经过上边包车型客车编写制定来布告调用方异步操作已经到位。

    将 IAsyncResult.IsCompleted 设为 true。

    激活 IAsyncResult.AsyncWaitHandle 再次回到的等待句柄。

    调用异步回调函数。

  要经过从 End 方法中抛出特别来代表不能得逞地实现异步操作。

  要在 End 方法被调用时一起完成有着未能如愿的操作。。

  考虑抛出 InvalidOperationException 很是 – 借使用户用同1个IAsyncResult 四遍调用 End 方法,或 IAsyncResult 是从另1个不相干的 Begin
方法重返的。

  要把 IAsyncResult.CompletedSynchronously 设为 true –
当且仅当异步回调函数将在调用 Begin 方法的线程中运作的时候。

  要保管在正确的线程中调用事件处理程序。与经典 Async
形式相比较,那是采取基于事件的 Async 形式的关键利益之一。

  要保管无论是操作已经成功,仍旧操作出错,如故操作被收回,都以种会调用事件处理程序。不应有让应用程序无停歇地等待一间永远不会发生的风波

  要保证在异步操作失利后,访问时间参数类的本性会吸引那么些。换句话说,假设有不当导致操作不可能完结,那么就不应当允许用户访问操作的结果。

  不要为回到值为空的法子定义新的事件处理程序或事件参数类型。要运用
AsyncCompleted伊夫ntArgs,AsyncCompleted伊夫ntHandler 或
伊夫ntHandler<AsyncCompleted伊芙ntArg>。

  要保管一旦在二个一步操作中落到实处了 PaogressChanged
事件,那么在操作的形成事件被触发之后,不该再冒出此类事件。

  要保管一旦应用了正式的 ProgressChanged伊芙ntArgs,那么
ProgressPercentage
始终能用来表示进程的百分比(不肯定要统统标准,但表示的终将要百分比)。假诺运用的不是明媒正娶进程,那么从
ProgressChanged伊芙ntArgs 派生3个子类会更适合,那种景况下相应保持
ProgressPercentage 为 0 ;

  要在有增量结果需求报告的时候动身 ProgressChanged 事件。

  要对 ProgressChanged伊芙ntArgs
举办扩大来保存增量结果数据,并用扩大后的时日参数类来定义 ProgressChanged
事件。

  要把增量结果报告与进程报告分开。

  要为每一个异步操作定义单独的 <MethodName>ProgreessChanged
事件和对应的事件参数类,来处理该操作的增量结果数据。

  

9.3 依赖属性

  要提供正视属性 – 假如急需用他们来支撑各样 WPF
性格,比如样式、触发器、数据绑定、动画、动态财富以及继续。

  要在统一筹划重视属性的时候继承自 DependencyObject
或它的子类型。该项目达成的品质存款和储蓄区非凡迅猛,它还自行扶助 WPF
的数码绑定。

  要为每一种正视属性提供健康的 CL昂科威 属性和存放
System.Windows.DependencyProperty 实例的国有静态只读字段。

  要通过调用 DependencyObject.GetValue 和 DependencyObject.SetValue
的办法来贯彻依靠属性。

  要用看重属性的名字加上“Property”后缀来定名注重属性的静态字段。

  不要显式地在代码中安装正视属性的暗中同意值,应该在元数据中设置暗中认可值。

  不要在质量的访问器中添加额外的代码,而应该利用正式代码来拜会静态字段。

  不要选用正视属性来保存保密数据。任何代码都能访问依赖属性,即便它们是个体的。

  不要把依赖属性的注脚逻辑放在访问器中,而应该把验证毁掉函数字传送给
DependencyProperty.Register 方法。

  不要在凭借属性的访问器中落到实处属性改变的打招呼,而应该向
PropertyMetadata
注册改成文告的回调函数,后者是依靠属性本身提供的一项特征,为了支持改变布告,必须选择该天性。

  不要在凭借属性的访问器中落到实处属性强制赋值逻辑,而应该向
PropertyMetadata
注册强制赋值的回调函数。后者是依赖属性本人提供的一项特征,为了扶助强制赋值,必须利用该本性。

  

9.4 Disopse 模式

  要为含有可处以项目实例的系列达成宗旨 Dispose 方式。

  要为类型达成基本 Dispose 方式并提供终结方法 –
假若类型持有必要由开发职员显式释放的花色,而且后者自个儿并未终止方法。

  考虑为类达成主旨 Dispose 格局 –
假诺类本人并不享有非托管财富或可处以对象,可是它的子类型却或许会持有非托管财富或可处以对象。

  要按上边包车型的士章程来贯彻 IDisposable 接口,即先调用
Dispose(true),然后再调用 GC.SuppressFinalize(this)。

  不要将无参数的 Dispose 方法定义为虚方法。

  不要为 Dispose 方法证明除了 Dispose() 和 Dispose(bool)
之外的别样其余重载方法。

  要允许数十次调用 Dispose(bool)
方法。他得以在第一次调用之后就什么样也不做。

  幸免从 Dispose(bool)
方法中抛出尤其,除非是殷切意况,所处的进程早已遭受损坏(比如泄漏、共享状态差异等,等等)。

  要从分子中抛出 ObjectDisposedException 十分 –
要是该成员在目的终结之后就没办法继续运用。

  考虑在 Dispose() 方法之外在提供3个 Close() 方法 – 假诺 close
是该领域中的两个正经术语。

  制止定义可完工类型。

  不要定义可告竣的值类型。

  要将类型定义为可完工类型 –
假设该项目要担负释放非托管财富,且非托管能源本身不具有终结方法。

  要为全部的可竣事类型实现基本 Dispose 情势。

  不要在终结方法中访问任何可完工对象,那样做存在相当大的高风险,因为被访问的目的或者早已被终止了。

  要将 Finalize 方法定义为受保障的。

  不要在甘休方法中放过任何至极,除非是沉重的系列错误。

  考虑创制一个用于热切景况的可完工对象 –
如若得了方法在行使程序域被威逼卸载或线程卓殊退出的景观下都不能够不要执行。

 

9.5 Factory 模式

  要优先利用构造函数,而不是优先利用工厂,因为与尤其的靶子组织机制比较,构造函数一般的话更便于采取、更平等,也更有益。

  考虑选择工厂 – 若是构造函数提供的目的创造机制不可能满足须求。

  要采用工厂 –
倘使开发人士大概不领会待成立的对象的稳当品种,比如对基类或接口编制程序就属于那种景观。

  考虑动用工厂方法 – 假如那是让操作不言自明的绝无仅有形式。

  要在转换风格的操作中动用 factory。

  要尽大概将工厂操作方法完结为方式,而不是兑现为属性。

  要通过措施的重临值而不是形式的出口参数来回到新创立的对象实例。

  考虑把 Create 和要创立的花色名连在联合署名,一回来命名工厂方法。

  考虑把要创设的门类名和 Factory
连在一起,一遍来命名工厂类型。例如,能够考虑把创造 Control
对象的厂子类型命名为 ControlFactory。

  

9.6 对 LINQ 的支持

  要兑现 IEnumerabl<T>,其目标是为着获取基本的 LINQ 支持。

  考虑完结 ICollection<T>,其目标是为着增加查询的性格。

  考虑达成 IQueryable<T> – 假诺非得要拜访传给 IQueryable
的积极分子的询问表达式。

  不要草率地完成IQueryable<T>,要知道那样做大概会对质量发生怎么样影响。

  要在 IQueryable<T> 的办法中抛出 NotSupportedException –
即使你的数据源上不支持该操作。

  要在新类型上将 Query 方式完结为实例方法 – 倘使在 LINQ
以外的场子,那些办法在档次中还是有存在的意思。不然,应该将它们达成为扩大方法。

  要让贯彻了 Query 格局在项目完成了 IEnumerable<T>。

  考虑在统一筹划 LINQ
操作符时,让它们重临领域蓄意的可枚举类型。尽管从实质上的话,Select
查询艺术能够再次回到任何项目,可是大家常见都愿意查询的结果是可枚举类型。

  防止只兑现 Query 方式的一某个 – 若是不期望退回到基本的
IEnuerable<T> 完成。

  要为有序连串定义单独的品种,从而将它和相应的无序系列分开。那样的档次应该定义
ThenBy 方法。

  要延迟执行实际的询问操作。对 Query
格局的绝半数以上成员来说,小编愿意它们只是成立2个新的靶子,并在枚举的时候才发生集合重负荷查询条件的要素。

  要将用于查询的恢弘方法放在主命名空间中的3个名为“Linq”
的子命名空间中。例如,为 System.Data 特性定义的增添方法被放在
System.Data.Linq 命名空间。

  要在参数中动用 Expression<Func<…>>,而不是
Func<…> – 尽管必要查询查询表达式。

 

9.7 Optional Feature 模式

  考虑将 Optional Feature 情势用于抽象中的可选天性。

  要提供二个简易的布尔属性来让用户检测对象是否协助可选本性。

  要在累积中校可选特性定义为虚方法,并在该方法中抛出
NotSupportedException 万分。

  

9.8 Simulated Convariance 模式

  考虑使用 Simulated Convariance 情势 –
假如急需有一种统一的类型来代表泛型类型的装有实例。

  要保证以等价的办法来落到实处基础类型成员和对应的泛型类型成员。

  考虑选用抽象基类来表示根基类型,而不是采用接口来代表根基类型。

  考虑用非泛型类型作为基础类型 – 假若这么的花色已经存在。

  

9.9 Template Method 模式

  幸免将国有成员定义为虚成员。

  考虑选拔 Template Method 情势来更好地控制扩张性。

  考虑以非秀成员的名字加“Core”后缀为名字,来定名为该费虚成员提供扩充点的受有限支撑的虚成员。

  

9.10 超时

  要先期让用户通过参数来制定超时间长度度。

  要优用 TimeSpan 来表示超时间长度度。

  要在逾期后抛出 System.TimeoutException 十分。

  不要通过再次回到错误码的法子来报告用户爆发了晚点。

  

9.11 可供 XAML 使用的花色

  考虑提供暗中同意构造函数 – 假诺想让项目能用于 XAML。

  要提供标记扩张 – 假使想让 XAML 读取程序能够成立不可变的项目。。

  防止定义新的种类转换器,除非那样的更换是自可是直观的。一般的话,应该将品种转换器的行使限制界定在
.NET 框架中早已采取了品种转换器的地点。

  考虑将 ContentPropertyAttribute 用于最常用的个性,从而获得更有益的
XAML 语法。

 

相关文章