第 9 章:常用的设计形式

9.1 聚合组件

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

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

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

  要在筹划聚合组件时使初阶化尽只怕地归纳,那样用户只需进行简短的初步化就可以动用组件。尽管某一项开首化是必需的,那么由于尚未对组件进行开始化而吸引的要命应该醒目地告诉用户应该怎么做。

  不要须求聚合组件的用户在2个光景中显式地实例化两个对象。

  要确保让聚合组件协理 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 方法被调用时3只达成全数未能如愿的操作。。

  考虑抛出 InvalidOperationException 很是 – 假设用户用同一个IAsyncResult 一次调用 End 方法,或 IAsyncResult 是从另二个不相干的 Begin
方法重返的。

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

  要力保在不利的线程中调用事件处理程序。与经典 Async
形式相比较,那是行使基于事件的 Async 形式的重大利益之一。

  要确保无论是操作已经已毕,如故操作出错,如故操作被撤回,都以种会调用事件处理程序。不应当让应用程序无停歇地等候一间永远不会生出的风云

  要确保在异步操作战败后,访问时间参数类的品质会抓住那么些。换句话说,假设有错误导致操作无法成功,那么就不该允许用户访问操作的结果。

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

  要保险一旦在1个一步操作中达成了 PaogressChanged
事件,那么在操作的做到事件被触发之后,不应有再出新此类事件。

  要保险一旦利用了正规的 ProgressChanged伊芙ntArgs,那么
ProgressPercentage
始终能用来代表进程的百分比(不必然要完全规范,但象征的一定要百分比)。若是接纳的不是业内进程,那么从
ProgressChanged伊夫ntArgs 派生两个子类会更适于,那种景色下应当维持
ProgressPercentage 为 0 ;

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

  要对 ProgressChanged伊芙ntArgs
举行伸张来保存增量结果数据,并用扩充后的流年参数类来定义 ProgressChanged
事件。

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

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

  

9.3 依赖属性

  要提供倚重属性 – 如若急需用他们来支撑种种 WPF
本性,比如样式、触发器、数据绑定、动画、动态财富以及一连。

  要在布置重视属性的时候继承自 DependencyObject
或它的子类型。该项目完结的性子存储区格外迅猛,它还自行帮衬 WPF
的数码绑定。

  要为每种依赖属性提供正常的 CLHighlander 属性和存放
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() 方法之外在提供二个 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
形式的半数以上成员来说,小编期望它们只是创造三个新的对象,并在枚举的时候才发生集合重负荷查询条件的成分。

  要将用于查询的扩大方法放在主命名空间中的三个名为“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 超时

  要先行让用户通过参数来制订超时长度。

  要先期采取 提姆eSpan 来代表超时长度。

  要在逾期后抛出 System.TimeoutException 格外。

  不要通过重回错误码的格局来告诉用户暴发了晚点。

  

9.11 可供 XAML 使用的品类

  考虑提供暗中认可构造函数 – 假如想让项目能用于 XAML。

  要提供标记扩张 – 若是想让 XAML 读取程序可以创设不可变的种类。。

  防止定义新的类型转换器,除非那样的更换是自然则直观的。一般的话,应该将品种转换器的利用限制限制在
.NET 框架中一度采纳了连串转换器的地点。

  考虑将 ContentPropertyAttribute 用于最常用的属性,从而赢得更便利的
XAML 语法。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图