`
t641339564
  • 浏览: 27189 次
  • 性别: 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()

{…}

}

分享到:
评论
发表评论

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

相关推荐

    系统架构设计师教程_第5章_软件架构设计

    《系统架构设计师教程》中的第五章,深入探讨了软件架构设计的核心概念、原则与实践,为读者提供了全面而深入的理解。 ### 一、软件架构设计的重要性 软件架构设计是软件开发过程中的关键环节,它决定了软件系统的...

    软件工程中的可维护性与可扩展性设计.pptx

    #### 第3章 可扩展性设计策略 **水平扩展** 水平扩展是一种通过增加服务器实例或节点来提升系统性能和容量的方式。这种方式可以有效地分担系统的负载,增强系统的容错能力。实现水平扩展的关键要素包括: - **...

    谭浩强版C程序设计(第三版) 第五章到第十三章答案

    综上所述,第五章至第十三章覆盖了C语言的基础到进阶内容,通过解答《谭浩强版C程序设计(第三版)》的课后习题,读者可以系统地掌握C语言的核心技能,为后续的软件开发打下坚实基础。提供的“C答案.doc”文档应该...

    谭浩强 C程序设计第三章课后答案

    压缩包中的"test3"可能是包含了第三章所有习题的源代码文件,这些源代码文件通常以".c"为扩展名,表示它们是用C语言编写的。通过阅读和分析这些源代码,学习者可以直观地看到如何将理论知识转化为实际的编程实践,这...

    Java语言程序设计与数据结构(基础篇)第5章课后习题代码chapter5.rar

    第五章的课后习题代码提供了实践机会,帮助读者巩固理论知识,提高编程技能。 在Java中,数据结构主要包括数组、链表、栈、队列、树和图等。数组是最基本的数据结构,它允许以固定大小存储同类型的数据。链表则通过...

    微机原理第五章作业 欢迎看看啊

    通过完成第五章的作业,学生能够更好地理解计算机存储系统的复杂性,从而在后续的学习中能够更有效地分析和解决问题。这份作业答案可以作为学习者自我检查和巩固知识的参考资料,同时也可以帮助他们在面对相关问题时...

    无线局域网电子课件第五章 无线局域网规划与设计

    《无线局域网规划与设计》第五章详细解读 无线局域网(WLAN)的规划与设计是构建高效、安全、可靠网络的关键环节。本章由陈南京主讲,内容涵盖设计目标、设计原则、需求分析等多个核心部分,旨在指导读者如何构建...

    第03章 从架构层面看设计模式02.pdf

    【第03章 从架构层面看设计模式02】主要探讨了如何在软件架构中应用设计模式,尤其是代理模式,以及如何结合其他模式优化系统。本章节通过一个电商设计模式实战案例,详细阐述了代理模式、享元模式、装饰者模式、...

    《软件工程》课件 第四章

    在《软件工程》课程的第四章中,我们深入探讨了软件设计的核心概念和方法,这一章包括了多个关键部分,涵盖了软件设计的不同方面。以下是基于提供的压缩包文件内容的详细知识点解析: 1. **4.1 软件设计的任务、...

    软件工程第5章传统软件设计.pptx

    在本讲座中,我们将探讨软件工程的第五章——传统软件设计,涉及的内容包括软件生命周期的不同阶段、设计方法以及设计原则。 首先,软件生命周期包括了软件的定义时期、开发时期和使用及维护时期。定义时期涵盖了...

    C语言程序设计第7章函数ppt课件.ppt

    "C语言程序设计第7章函数ppt课件.ppt" 本资源是关于C语言程序设计第7章函数ppt课件的概括,包含了函数的定义、函数的调用、函数的原型、函数的参数传递、函数的返回值、递归函数、函数的封装、函数的重用、函数的...

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

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

    自考ava语言程序设计(一)课本源代码第五章

    "ava语言程序设计(一)课本源代码第五章"提供了一个宝贵的资源,帮助学生更有效地理解和实践编程概念。本章主要涵盖了ava语言的核心部分,包括类、对象、继承、封装和多态等关键主题。 在第五章,你将深入学习ava...

    软件工程中的扩展性与可维护性.pptx

    #### 第二章 软件设计原则与扩展性 **SOLID原则**是软件设计中的五个基本原则,具体包括: - **单一职责原则(Single Responsibility Principle, SRP)**:一个类应该只负责一项职责。 - **开闭原则(Open/Closed ...

    大规模并行计算通信可扩展性-分析、优化与模拟.doc

    最后,设计并实现了虚实结合的执行驱动模拟器VACED-SIM(第五章)。VACED-SIM是基于离散事件模拟的新型模拟方法,它结合了虚模拟和实模拟,以及轨迹驱动和执行驱动的优势,尤其适用于大规模并行计算的可扩展性预测。...

    混凝土设计原理第5章思考题和习题集答案解析.doc

    《混凝土设计原理》第五章主要探讨的是混凝土受弯构件的斜截面受力性能和破坏模式,以及设计中应考虑的关键因素。以下是本章主要内容的详细解析: 首先,受弯构件在跨中产生垂直裂缝而支座附近产生斜裂缝的原因在于...

    管理信息系统:第六章 系统设计.ppt

    【管理信息系统:第六章 系统设计】 在深入探讨第六章的内容之前,首先要明确面向对象系统设计(Object-Oriented System Design, OOSD)的基本概念。系统设计是软件开发过程中至关重要的一环,它是在面向对象分析...

    软件工程作业第五章答案.doc

    本资源为软件工程作业第五章答案,涵盖了软件设计的相关知识点,包括模块耦合、模块内聚、软件结构设计等。 1. 模块耦合 耦合是指模块之间的相互依赖关系。耦合的类型有: * 内容耦合:模块之间共享同一个数据...

    VC++面向对象与可视化程序设计(第三版)黄维通 第五章

    《VC++面向对象与可视化程序设计...通过深入学习黄维通的《VC++面向对象与可视化程序设计》第五章,读者不仅可以掌握C++的面向对象编程技术,还能熟练运用Visual C++进行实际项目开发,为未来的职业生涯打下坚实基础。

Global site tag (gtag.js) - Google Analytics