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

第5章 为扩展性而设计

阅读更多

5.1. 扩展机制

5.1.1. 非密封类

密封类( sealed class)既无法派生子类,也无法扩展。与此相反,非密封类(unsealed class)可以派生子类并进行扩展。

ü 考虑用不包含任何虚成员或保护成员的非密封类来为框架提供扩展性,这种方法的开销不高,用户也喜欢。

5.1.2. 保护成员

保护成员本身不能提供任何的扩展性,但他们能加强派生子类这一扩展机制。可以用他们来暴露高级的定制选项,同时可以避免不必要地是公用接口复杂化。

ü 考虑将保护成员用于高级定制。

ü 要在对安全性、文档及兼容性进行分析时,把非密封类保护成员作为公有成员来对待。

5.1.3. 事件与回调函数

回调函数是一种扩展机制,它是框架能够实用委托来调用用户代码,这些委托是作为方法的参数传给框架的。

事件是一种特殊的回调函数,它为用户提供一致的语法,使用户能够非常方便地把委托提供给框架。

Timer timer = new Timer(1000);

timer.Elapsed += delegate

{…}

与虚成员相比,回调函数可以用来提供相当强的扩展性。同时由于不需要对面向对象设计有非常深入的了解,因此回调函数和事件能够为更广泛的丌发人员所接受。此外,回调函数能够提供动态(运行时的)扩展性,而虚成员则只能提供静态(编译时的)扩展性。

回调调函数的主要缺点在于,与虚成员相比显得太过重量级。通过委托进行调用的性能不如调用虚成员。另外,由于委托是对象,因此它们会消耗内存。

ü 考虑实用回调函数来让框架能够执行用户提供的代码。

ü 考虑实用事件来让用户定制框架的行为,这样就不需要用户对面向对象设计有深入的了解。

ü 要优先使用事件,而不是简单的回调函数。

û 避免在对性能要求很高的API中使用回调函数。

ü 要理解在调用委托时可以执行任何代码,这可能会引起安全性、正确性及兼容性的问题。

5.1.4. 虚成员

虚成员可以被覆盖,从而可以改变子类的行为。从提供的扩展性来看,虚成员与回调函数旗鼓相当,但从执行性能和内存消耗来看,虚成员更胜一筹。此外,如果要为已有的类型创建一个特殊的版本(特化),那么使用虚成员会感觉更白然。

与回调函数相比,虚成员的主要缺点在于它的行为只能静态修改(在编译时修改),而回调函数的行为则可以动态修改(在运行时修改)。

虚成员和回调函数一样,设计、测试及维护的开销都非常高,这是因为用户可能会用设计者意料之外的方式来覆盖虚函数,还可能会执行任何代码。

û 不要使用虚成员,除非有合适的理由,同时你对设计、测试及维护虚成员的开销有清楚的认识。

ü 要优先使用受保护的虚成员,而不是公有的虚成员。公有成员应该通过调用受保护的虚成员的方式来提供扩展。

public Control

{

public void SetBounds(…)

{

SetBoundCore(…);

}

protected virtual void SetBoundCore(…)

{…}

}

5.1.5. 抽象(抽象类型与抽象接口)

û 不要提供抽象,除非为该抽象开发出具体实现并用到该抽象的API对其进行过实际测试。

ü 要在设计抽象时,谨慎地选择抽象类或是抽象接口。

ü 考虑为抽象的具体实现提供参考测试。

5.2. 基类

严格地说,当一个类有另一个类派生自它时,这个类就成为了基类。此处我们把基类限定为这样的类:其设计目的不是为了直接使用或提供常用的抽象,而是为了让其他类通过继承它来重用它的默认实现。

基类通常位于继承层次的中部,根位于顶部,而一些自定义实现则位于底部。基类是为了帮助用户实现抽象。例如,框架为有序项集提供的抽象之一是IList<T> 接口,但要实现IList<T>并不容易,因此框架提供了许多基类,比如Collection<T>KeyedCollection<TKey,TItem>,以帮助用户实现自定义的集合。

public class OrderCollection : Collection<Order>

{

protected override void SetItem(int indext, Order item)

{

if (item == nullthrow new ArgumentNullExcaption(...) ;

base.SetItem(index, item) ;

}

}

ü 考虑使基类为抽象类,即使它们并不包含任何抽象成员。

ü 考虑把基类用于主要场景的类型分开,放到单独的命名空间中。

û 避免在命名基类时使用“Base”后缀,如果该类会用于公用API

5.3. 密封

密封是一种阻止扩展的有效机制。开发人员既可以密封整个类,也可以密封类中的单个成员。密封整个类可以是用户不能继承该类,密封一个成员可以使用户不能覆盖该成员。

public class NonNullCollection<T>:Collection<T>

{

protected sealed override void SetItem(int index, T item)

{…}

}

û 不要把类密封起来,除非有恰当的理由。

把类密封起来的恰当理由包括:

Ø 类为静态类。

Ø 类的保护成员保存了需高度保密的机密信息。

Ø 类继承了许多虚成员,把这些虚成员一个一个密封起来代价太高,还不如把这个类都密封起来。

Ø 类是attribute,需要能在运行的时候快速查找。

密封的attribute在性能上比不密封的attribute略好。

û 不要在密封类中声明保护成员或虚成员。

ü 考虑在覆盖成员时,将其密封。

public class FlowSwitch:SourceSwitch

{

protected sealed override void OnValueChanged()

{…}

}

分享到:
评论
发表评论

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

相关推荐

    MySQL性能调优与架构设计(中文版)

     第15章 可扩展性设计之Cache与Search的利用  第16章 MySQL Cluster  第17章 高可用设计思路及方案  第18章 高可用设计之MySQL监控 附录A 实验测试Schema创建脚本 附录B MySQL部分系统参数说明及设置建议 ...

    软件架构设计(温昱)--第4章 软件架构视图

    讨论 软件架构视图 ...3、为开发员设计:关注“软件运行时质量属性”(可扩展性、可用重用性、可移植性、易理解性、易测试性)。 4、为管理员设计:为分工管理、协调控制和评估监控等工作提供清晰的基础。

    新编MCS-51单片机应用设计

    第5章 MCS—51的定时器/计数器 第6章 MCS—51的串行口 第7章 MCS—51扩展存储器的设计 第8章 MCS—51的UO接口扩展 第9章 MCS—5重与键盘、显示器、拨盘、打印机的接口设计 第10章 MCS—51与D/A、A/D的接口 第11章 ...

    设计数据密集应用 中文完整版带目录

    《Designing Data-Intensive ...第五章:复制 第六章:分区 第七章:事务 第八章:分布式系统的麻烦 第九章:一致性与共识 第三部分:衍生数据 第十章:批处理 第十一章:流处理 第十二章:数据系统的未来 ....

    WPF揭秘 第四章 wpf 开发

     第5章 尺寸缩放、定位与变换元素   第6章 使用面板做布局   第7章 构建并部署应用程序  第三部分 为专业开发人员设计的功能  第8章 资源   第9章 数据绑定   第10章 样式、模板、皮肤和主题 233...

    毕业设计: Java项目springboot基于SpringBoot的论坛系统(源码 + 数据库 + 论文)

    第五章 系统实现 21 5.1 管理员功能实现 21 5.1.1 版主管理 21 5.1.2 用户管理 21 5.1.3 留言版管理 22 5.2 版主功能实现 22 5.2.1 论坛管理 22 5.2.2 新闻信息查看 23 5.2.3 个人信息 24 5.3 用户功能实现 24 5.3.1...

    WPF揭秘 第二章 wpf 开发

     第5章 尺寸缩放、定位与变换元素   第6章 使用面板做布局   第7章 构建并部署应用程序  第三部分 为专业开发人员设计的功能  第8章 资源   第9章 数据绑定   第10章 样式、模板、皮肤和主题 233...

    WPF揭秘 第三章 wpf 开发

     第5章 尺寸缩放、定位与变换元素   第6章 使用面板做布局   第7章 构建并部署应用程序  第三部分 为专业开发人员设计的功能  第8章 资源   第9章 数据绑定   第10章 样式、模板、皮肤和主题 233...

    WPF揭秘 第一章 wpf 开发

     第5章 尺寸缩放、定位与变换元素   第6章 使用面板做布局   第7章 构建并部署应用程序  第三部分 为专业开发人员设计的功能  第8章 资源   第9章 数据绑定   第10章 样式、模板、皮肤和主题 233...

    [Java设计模式(第2版)(Design.Patterns.in.Java).John.Metsker

    第5章 合成(composite)模式 39 第6章 桥接(bridge)模式 52 第7章 职责型模式介绍 62 第8章 单例(singleton)模式 67 第9章 观察者(observer)模式 72 第10章 调停者(mediator)模式 85 第11章 代理(proxy)模式 97 第12...

    软件管理系统概要设计-史上最标准模板.docx

    2.2.2 可扩展性与可维护性考虑 4 2.2.3 系统安全性考虑 4 2.3 运行环境 5 2.3.1 应用服务器 5 2.3.2 数据库服务器 5 2.4 系统体系架构 5 2.4.1 系统架构图 6 2.4.2 物理部署图 6 2.5 关键技术 7 2.5.1 基于角色的...

    毕业设计: Java项目springboot197基于springboot的毕业设计系统(源码 + 数据库 + 论文)

    第五章 系统实现 24 5.1管理员功能实现 24 5.1.1 课题信息管理 24 5.1.2 成绩统计报表 24 5.1.3 教师管理 25 5.2 教师功能实现 26 5.2.1 选题申请管理 26 5.2.2 课题任务管理 26 5.2.3 最终成绩管理 27 5.3 学生功能...

    基于Web的高校学生选课系统设计与实现.rar(论文+项目源码)

    第一章 绪论 2 1.1 课题目的及意义 2 ...第五章 选课系统的实现 16 5.1 系统功能模块功能 16 5.2 课程选择模块实现 16 5.3 成绩查询 16 5.4 开课管理 17 第六章 选课系统测试 17 6.1系统调试的目的和意义 18 .......

    毕业设计: Java项目springboot古典舞在线交流平台的设计与实现(源码 + 数据库 + 论文)

    论文目录: ...第五章 系统的实现 17 5.1 用户功能模块的实现 17 5.1.1系统主界面 17 5.1.2用户注册界面 17 5.1.3论坛交流界面 18 5.1.4课程详情界面 19 5.1.5购物车界面 19 5.1.6我的订单界面 20 5

    毕业设计: Java项目springboot基于springboot的疾病防控综合系统(源码 + 数据库 + 论文)

    第五章 系统实现 22 5.1管理员功能实现 22 5.1.1 核酸检测管理 22 5.1.2 接种记录管理 22 5.1.3 物资管理 23 5.1.4 物资申请管理 23 5.1.5 出入记录管理 24 5.2 用户功能实现 25 5.2.1 打卡管理 25 5.2.2 接种记录...

    毕业设计: Java项目springboot基于springboot+vue的游戏交易系统(源码 + 数据库 + 论文)

    第五章 系统实现 23 5.1管理员功能实现 23 5.1.1 商品管理 23 5.1.2 商品评价管理 23 5.1.3 商品订单管理 24 5.1.4 订单投诉管理 24 5.1.5 用户管理 25 5.2 用户功能实现 26 5.2.1 商品信息 26 5.2.2 确认下单 26 ...

Global site tag (gtag.js) - Google Analytics