设为首页 加入收藏

TOP

C++ 类层次结构的设计方法学
2014-11-24 12:46:51 来源: 作者: 【 】 浏览:0
Tags:层次 结构 设计 方法学

关于 C++ 类层次结构的设计方法学,note-to-self + keynote + cross-reference 式笔记


本文精炼于 [CPP LANG] 12.4, 15.2 的 BBWindow 示例,只涉及 design
Syntax 参考 [CPP LANG] Ch12, 15; [CPP PRIMER] Ch17, 18
Play with bits 参考 [CPP OBJMODEL] 5.2


keyword: class hierarchy, multiple inheritance, abstract class, virtual base class, abstract factory, clone


目录


IValBox: 取得用户输入整数的 GUI 元素之抽象类,它不绑定具体 GUI 元素,如 slider 滑块, dial 拨盘


IValSlider: 滑块式 IValBox 实现,类似的还有 IValDial 拨盘式实现,代表 IValBox 类层次中具体的 GUI 元素。这些类可以进一步扩展,如从 IValSlider 派生出 PopupIValSlider


BBWindow: 第三方提供的 GUI 元素实现,类似 MFC 的 CWnd 等。IValBox 的类层次依靠 BBWindow 的类层次实现 GUI 特性(画图之类)。BBWindow 只是形式名,它可以替换,其意义就像将 MFC 换成 Qt 一样,这使得 IValBox 的类层次能够减小对特定 GUI 元素实现的依赖


UML: Old Hierarchy



设计要义:


UML: Separate Implementation and Interface



接口线:接口继承形成的层次
实现线/扩展线:实现继承形成的层次


设计要义:


这是分离实现和接口后得到的益处


UML: Substitute Implementation



图中的 BBSlider 表示 BBIValSlider 可藉由以存在的更特定的 GUI 元素实现,而不是更一般的 BBWindow,就像是从 MFC 的 CWnd 改为了 CSliderCtrl


使用同样的方法进行扩展就能得到 Big One:


UML: Substitute Implementation, Complicated



无需纠结上图具体含义,这里的设计推论更有意思:一个系统展现给用户的应该是一个抽象类的层次结构,其实现所用的是一个传统的层次结构
有点教条吧?试问,传统的层级结构从何而来?我们要做一个横跨多种 GUI 框架之上的框架么?


用 virtual 基类消除 replicated base class 重复基类,见 [EFFECT CPP] Item 40


这种用法的目的有二:


UML: Share Implementation



这里 Diamond-shaped Inheritance 钻石形继承的意义:让实现 PopupIValSlider 的类(即 BBPopupIValSlider)共享实现 IValSlider 的类(即 BBIValSlider)中的实现,以减少编码


于是另一个有意思的推论:组成应用之接口的抽象类的所有派生都应该是 virtual 的,[EFFECT CPP] Item 40 也说 public 继承应该总是 virtual
但是现实不能如此,最简短的反驳是效率因素,见 [CPP LANG] 15.2.5 和 [EFFECT CPP] Item 40


可藉由无 data member class 进行重复基类方式的优化
于是,饶了一圈又回来了


构造函数不可能是 virtual 的,道理很简单:不知道对象的确切类型,又如何构造它(构造函数的实质是对象内布局的 bits 初始化)


抽象工厂和 Clone 模式被戏称为 virtual constructor 虚拟构造函数,因为它们用 virtual 函数迂回完成构造函数的任务:根据某些线索创建对象


绝对的抽象创建(没有线索)是不可能的,即没有语法支持(virtual 构造函数),也没有逻辑意义:当你想要铅笔时,可以说我要铅笔,也可以说我要铅笔盒中的东西(带线索的抽象),但不能只说我要东西(不带线索的抽象)


Why abstract class


UML: Abstract Factory



减小对象创建时,对特定实现类(构造函数)的依赖,如当创建 IValDial 时,必须使用 BBIValDial 或 LSIValDial 的构造函数


当抽象类层次结构较复杂时,并且有从一个实现系统变为另一个实现系统(如从 BBWindow 变为 LSWindow)的预期时,需要一种一次性装入实现系统中各种创建对象的方法,这时抽象工厂就会发挥作用:


1、2 是程序初始化阶段执行的设置,3、4 是程序例行阶段的行为


于是,抽象工厂是和抽象类层次伴生的


UML: Clone Pattern



Why clone


手上有一个对象,只知道它的抽象类型(确切类型已丢失),要复制这种对象的大量副本,并且副本要和其确切类型一致


可以定义一个 Clonable 抽象基类,以规约 clone 函数,但不是必须的


Clone 模式可从函数 override 的返回值类型的 covariance 协变中受益。VC 2005+ 支持协变


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++ 杨辉三角,没有使用数组 下一篇iPhone 4 实现 HTC Sense 时钟动..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·常用meta整理 | 菜鸟 (2025-12-25 01:21:52)
·SQL HAVING 子句:深 (2025-12-25 01:21:47)
·SQL CREATE INDEX 语 (2025-12-25 01:21:45)
·Shell 传递参数 (2025-12-25 00:50:45)
·Linux echo 命令 - (2025-12-25 00:50:43)