C++设计模式第四讲_第1页
C++设计模式第四讲_第2页
C++设计模式第四讲_第3页
C++设计模式第四讲_第4页
C++设计模式第四讲_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C+设计模式教程第四讲:UIPLib设计模式(一) (组合模式、迭代器模式、策略模式、适配器模式、装饰模式)主讲人:步磊峰 UIPower 3D界面引擎负责人前言: 2 在前面三讲中,我们详细讲解了创建模式。由于创建模式相对来说功能比较单一,而结构模式和行为模式涉及到软件架构以及对象间通信关系。为了更好的演示相关设计模式,特意编写了UIPLib以及基于UIPLib上的UIPPaint应用程序来演示涉及到的相关行为和结构模式: UIPLib用到的模式: 已讲解过的模式: 单例模式(CApplication) 工厂模式(渲染系统) 将要讲解的模式: 组合模式(控件系统) 迭代器模式(CArrayI

2、terator,节点迭代器) 策略、装修、适配模式(节点迭代器) 观察者模式(事件系统) 模板方法模式 UIPaint用到的模式: 将要讲解的模式: 中间者模式(UIPLib和UIPPaint的纽带) 状态模式 (各种图元的切换) 命令模式 (实现Undo(Ctrl-Z)/Redo(Ctrl-Y)功能) 访问者模式 (图元的绘制) 职责链模式 (F1帮助系统)第一节: 组合模式(控件系统)3意图: 将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使用户对单个对象和组合对象的使用具有一致 性。 由意图描述可知,组合就是对象的集合,其中一个对象既可以是一个组合,也可以是一个简

3、单的、单一的对象。 很符合树的数据结构模式。 在整篇教程中,我们将树结构等同于组合模式,具有互换性。 在树的术语中,对象可以使带有其他分支的节点,也可以是叶子。 第一节: 组合模式(控件系统)4开发中的存在的问题: 在实际开发中遇到的问题是:对于组合中的所有对象都要求具有一个简单的,单一的访问接口并要求能区分节点和叶 子 ,这两者是矛盾的。节点可以由孩子并允许添加孩子。而叶子节点不允许有孩子,也不允许添加孩子。 当我们要区分叶子和节点时,可能使用的一种结构方式: struct ICompositeBase virtual ICompositeBase* GetParent() = 0; vir

4、tual ICompositeBase* GetRoot() = 0; virtual bool IsLeaf() const () = 0; ; struct CLeaf : public ICompositeBase virtual ICompositeBase* GetParent(); virtual ICompositeBase* GetRoot(); virtual bool IsLeaf() const return true; ; struct CNode : public ICompositeBase virtual ICompositeBase* GetParent();

5、virtual ICompositeBase* GetRoot(); virtual bool IsLeaf () const return false; virtual bool AddChild( ICompositeBase* c); virtual bool RemoveChild(int idx); virtual vector GetChildren(); ;第一节: 组合模式(控件系统)5 在这种区分叶子和节点的组合模式中,存在两个问题: 1) 叶子和节点虽然都是ICompositeBase的子类,但是CNode对ICompositeBase进行了接口函数的添加。这意味着当 我们

6、 要进行树遍历的时候,需要判断是否是CNode节点,如果是,要将ICompositeBase指针强转成CNode指针, 然后进行CNode的相关操作,它违反了”Composite使用户对单个对象和组合对象的使用具有一致性“的意图。2) 区分叶子和节点的组合模式,导致叶子不能添加儿子。如果一个职位升职系统中,小职员使用叶子表示,那么他永远 都只能当小职员,永远没法升职到团队领导。剥夺了小职员奋斗的目标。 第一节: 组合模式(控件系统)6开发中的存在的问题: 在实际开发中遇到的问题是:对于组合中的所有对象都要求具有一个简单的,单一的访问接口并要求能区分节点和叶 子 ,这两者是矛盾的。节点可以由孩子

7、并允许添加孩子。而叶子节点不允许有孩子,也不允许添加孩子。 当我们要区分叶子和节点时,可能使用的另外一种结构方式: struct ICompositeBase virtual ICompositeBase* GetParent() ; virtual ICompositeBase* GetRoot(); virtual bool IsLeaf() const () return true; virtual bool AddChild( ICompositeBase* c); virtual bool RemoveChild(int idx); virtual vector GetChildre

8、n(); ; struct CNode : public ICompositeBase virtual bool IsLeaf() const () return false;struct CLeaf : public ICompositeBase /抛出异常 virtual bool AddChild( ICompositeBase* c); /抛出异常 virtual bool RemoveChild(int idx); /返回的vector.size() 必须等于0 virtual vector GetChildren(); ; 第一节: 组合模式(控件系统)7 在这种区分叶子和节点的组

9、合模式中: 1) 叶子和节点都是ICompositeBase的子类,具有一致的接口函数。这意味着当我们 要进行树遍历的时候,不需要判断 是否是CNode节点还是CLeaf节点,也不需要强制转换了。很符合我们的意图”Composite使用户对单个对象和组合 对象的使用具有一致性“的意图。2) 区分叶子和节点的组合模式,导致叶子不能添加儿子。如果一个职位升职系统中,小职员使用叶子表示,那么他永远 都只能当小职员,永远没法升职到团队领导。剥夺了小职员奋斗的目标。3) 如果仍旧使用职位升值系统,并且允许小职员也能够升职的话,我们只需要让小职员继承自CNode,并且其儿子节点 数组为空,这种情况下就可以

10、进行升职了。由此可见,区分叶子和节点或者更进一步,我们不区分叶子还是节点,都可以看成是组合模式。我们的控件系统使用的是不区分叶子和节点的模式。即使某个节点无儿子,也可在运行时添加儿子节点。 第一节: 组合模式(控件系统)8 UIPLib中的组合模式中类的继承关系: 第一节: 组合模式(控件系统)91、class CNode类:基类,代表一个组合模式。定义了一系列接口方法。2、template class CTypeNode : public CNode 模板类,继承自CNode,该类必须被继承。3、class CControlBase : public CTypeNode 我们从CTypedN

11、ode继承。由于在CTypeNode中,我们实现了所有模板化的操作。 例如 所有返回CNode*的函数,由于CTypedNode经过override,都会返回CControlBase*,这样更加具有通用性。 所有的控件都可以继承自CControlBase类,进行扩展。例如CButton,CCombox等都可以继承自CControlBase。4、class CControlManager : public CControlBase 组合(或树)结构的根节点。程序入口类CApplication持有一个CControlManager类的指针,代表根节点。 第二节: 组合模式(控件系统)实现要点101

12、、树节点析构: 它必须是深度优先,后根遍历的递归析构过程。 第二节: 组合模式(控件系统)实现要点112、区分Remove和Detach操作: 第二节: 组合模式(控件系统)实现要点123、节点添加时要注意防止循环引用以及保证父亲的唯一性: 第三节: 在控件系统中使用组合模式的优点13 第三节: 在控件系统中使用组合模式的优点14优点: 1、我们可以在运行时任意添加或删除子节点,从而形成复杂的节点树。2、控件的组合层次树蕴含天然的深度遮挡关系,在渲染和碰撞检测时需要这种深度遮挡关系。 第三节: 在控件系统中使用组合模式的优点15优点: 3、很容易进行坐标系统的变换。在我们的控件体系中,在设置位

13、置时候,使用相对于父控件偏移的局部坐标系统。 而我们的碰撞检测以及局部刷新使用的是基于ClientRect的全局坐标系统,而使用组合层次关系,我们可以非常容易进行局部-全局以及全局-局部坐标的转换: 第三节: 在控件系统中使用组合模式的优点16 第三节: 在控件系统中使用组合模式的优点17优点: 4、有利于控件父子之间的裁剪(Clip),既子控件的尺寸如果超过父控件的尺寸,那么子控件超过部分必须被裁剪掉。 第四节:迭代器模式18在前面的组合模式中,我们使用的都是递归方式对组合模式进行遍历。事实上,我们可以使用迭代器方式获得同样的效果,并且避免了递归调用。那么我们来看一下如何实现迭代器: 第五节

14、:迭代器+策略模式19迭代器意图:提供一种方法顺序访问聚合对象中各个元素,而又不需暴露该对象的内部表示。我们前面定义了一个迭代器模板接口。我们会发现对于一个线性存储的容器来说,有两种迭代顺序: 既 从左到右的迭代顺序 从右到左的迭代顺序我们有两种实现方式进行解决: 1)定义两个迭代器,如果std容器中一样,正向迭代器,反向迭代器。 2)使用策略模式,以模板参数传入。我们使用第二种方式实现。 第五节:迭代器+策略模式20策略模式意图:定义一系列的算法,将他们一个个封装起来,并且使他们可以相互替换。本模式使得算法可独立于使用 它的客户而变化。 第六节:ArrayIterator实现21 第七节:组合(树节点)迭代+策略+装饰+适配模式22装饰模式意图:动态的给一个对象添加一些额外的职责,装修模式相比生成子类来说更灵活。适配器模式意图:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的哪些类 可以一起工作。 第七节:组合(树节点)迭代+策略+装饰+适配模式23 第七节:组合(树节点)迭代+策略+装饰+适配模式24 第七节:组合(树节点)迭代+策略+装饰+适配模式25 第七节:组合(树节点)迭代+策略+装饰+适配模式26 第七节:组合(树节点)迭代+策略+装饰+适配模式27 第八节:组合(树节点)先根迭代器的实现28 第九节:组

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论