




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C+设计模式教程第七讲:UIPPaint设计模式(实现篇) (中间者、门面、状态、命令、访问者、职责链设计模式)主讲人:步磊峰 UIPower 3D界面引擎负责人第一节:整体架构UML图2 第一节:整体架构UML图3 第一节:整体架构UML图4 第二节:实现:访问者模式5意图: 表示一个作用于某对象结构中各个元素的操作。它使你可以在不改变各个元素的类的前提下定义作用于这些元素的 新操作。 用途: 1、一个对象结构包含很多类,他们有不同接口,而你想对这些对象实施一些依赖于其具体类的操作。 2、定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重新定义对所有访问者 的接
2、口,这可能需要很大代价。如果对象结构类经常改变,那么还是在该对象结构类中定义相关操作较好。 第二节:实现:访问者模式6根据需求: 我们会发现当处于CRectState时候,鼠标点击PaintArea时,需要创建一个以鼠标点击处为中心点的形状。 因此我们需要形状(或者叫图元) 目前支持三种图元 : CRectShape,CCircleShape,CTriangleShape,他们都继承自CShapeBase类,每种图元都能 被点中并且被填充,因此需要支持鼠标碰检事件。 所有的图元我们需要使用CShapManager来进行管理。 第二节:实现:访问者模式7 图元的绘制有两种方式: 1、在每个CSh
3、apeBase中定义一个虚函数Render(),每个子类都override Render函数,实现绘制代码,这意味着 所有的绘制代码都分散在每个实际的子类中。 2、 我们使用访问者模式,所有的实际子类的绘制代码全部放在CDrawerVisitor类中,如果要修改或增加功能,只要 修改CDrawerVisitor类就可以了。我们使用该方式实现图元的渲染。 CShapeBase中有一个纯虚函数: 第三节:实现:状态模式8意图: 允许一个对象在其内部状态改变时改变他的行为。用途: 1、 一个对象的行为取决于他的状态,并且他必须在运行时根据状态改变行为。 2、 一个操作中含有庞大的多分支的条件语句。这
4、个状态通常用一个或多个枚举常量表示。通常多个操作包含这一 相同的条件结构 。State模式将每个条件分支放入一个独立的类中。这使得你可以根据对象的自身情况将对象 的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。 第三节:实现:状态模式9根据需求: 当我们鼠标点中某个IconButton时,会触发Selected为true的事件,或许我们可以直接监听该事件作出要绘制哪 个类型的Shape的行为,但是这种方式使Shape和控件系统紧密耦合。我们换种思路。 我们会发现当选中某一个按钮时,每个按钮所做的事情不一样,也就是说图形编辑器的状态会影响程序要执行的 动作。这种情况特别适合使用状态模
5、式进行设计。因此我们引进一个中间层,让IconButton的状态切换与状态机 进行交互。使用状态模式我们能够显著的消除掉if/else或switch/case语句的使用。 上述分析后,我们会发现,每一个IconButton对应一个状态,例如RectButton选中时,对应的是CRectState。 CircleButton选中时,切换到CCircleState。因此我们只要监听IconButton的Selected事件,在事件响应函数 中进行状态的切换。那么由谁来进行状态切换呢? 状态设计模式涉及到两个层次,第一层次是CStateManager类负责所有状态管理,其持有一个CurrentSta
6、te的指 针,用于指向当前的状态。当CStateManager设置状态时,最好能够发送状态发生改变的消息,并且 CurrentState针指向刚设置的状态。因此由CStateManager来进行状态切换是非常合适的。 第三节:实现:状态模式10 第二个层次是CStateBase以及所有的子类。 第三节:实现:状态模式11 那么StateBase需要哪些操作呢? 根据需求:我们会发现当处于CRectState时候,鼠标点击PaintArea时,需要创建一个以鼠标点击处为中心点的 Rect形状。而其他例如处于CCircleState,CTriangleState状态时,表现形式与CRectStat
7、e相同,唯一 区别就是产生的形状不同而已。 当处于CFillState时,点击PaintArea控件中任意存在的形状,都会填充点中的图形。 因此我们会发现都是PaintArea鼠标点击有关,因此最起码StateBase中需要一个虚函数例如: virtual void MouseDown(const Point& pt)的函数。 为了更加灵活的处理切换状态,例如有一种需求,假设当我们选中绘制图像状态时使用正常的鼠标指 针,而在选中CFillState时,要使用一个油漆桶鼠标指针,这时候就需要我们能够响应状态切换的消息。 因此再增加两个状态切换的虚函数: virtual void OnEnter(
8、) /进入当前状态我们应该要做什么事情呢? virtual void OnLeave() /离开当前状态我们应该要做什么事情呢? 第四节:实现:命令模式12意图: 将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化; 对请求排队或记录请求日志,以支持可撤销的操作。用途: 1、接口回调。Command模式是回调机制的一个面向对象的替代品。 2、在不同时刻指定,排列和执行请求。 3、支持Undo/Redo操作。 4、支持修改日志。 5、 支持事务操作。 第四节:实现:命令模式13根据需求: 我们会发现当处于CRectState时候,鼠标点击PaintArea时,需要创建一个以鼠标点
9、击处为中心点的形状。 并且支持形状的创建和撤销操作,意味着我们支持形状创建的Undo/Redo功能。 我们定义ICommand接口用于支持Undo/Redo功能。该接口具有Execute()接口函数支持Redo操作,Undo()接口函 数用于支持Undo功能。 CShapeCreateCommand实现了ICommand接口,用于支持形状的创建和撤销。该命令是在: StateBase:MouseDown时被添加到CUndoManager中进行管理的。 CUndoManager类用于管理所有的命令对象,需要支持三个功能: 1、 命令的添加 2、 Undo栈和Redo栈的交互 3、 记录从当前开始
10、往前N个命令(N代表最多可以Undo/Redo多少步) 第五节:实现:中间者模式14意图: 用一个中介对象来封装一系列交互。中间者使个对象不需要显式的相互引用,从而使其耦合松散,而且可以独立的 改变他们之间的交互。 用途: 1、一组对象以定义良好但是复杂的方式进行通讯。产生的相互依赖关系结构混乱且难以理解。 2、一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。 3、想定制一个分布在多个类中的行为,而又不想生成太多的子类。 第五节:实现:中间者模式15 前面已经将涉及到应用程序交互的类都定义出来了,那么他们之间如何协作呢? 比较清晰的方式是划分模块: UIPaint模块-中间
11、者类-UIPLib模块。 中间者类知道所有的UIPaint模块的对象,而UIPaint模块的对象,例如每一个StateBase的子类都能够查找到中间者类。 中间者类监听UIPLib中的控件的所有输入事件,例如监听CIconButton的Select事件,根据哪个CIconButton被选中, 作出响应的状态切换(调用中间者类所拥有的StateManager,然后调用StateManager的SetCurrentState函数使状态 发生切换) 所有的输出也通过中间者类进行,监听CPaintArea类的RenderEvent,将所有UIPPaint中的图元渲染到CPaintArea控 件上。 第
12、六节:实现:门面模式16意图: 为子系统的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得子系统更加容易使用。 用途: 1、当你要为一个复杂的子系统提供一个简单的接口。Facade可以提供一个简单的缺省的视图,这一视图对大多数 用户来说已经足够了,而那些需要更多定制特性的用户可以越过Facade层。 2、客户程序与抽象类的实现部分之间存在很大依赖性。引入Facade将这个子系统与客户以及其他的子系统进行分 离,可以提高子系统的独立性和可移植性。 3、当你需要构建一个层次结构的子系统时,你可以使用Facade模式定义子系统的每层的入口点。如果子系统之间 相互依赖,你可
13、以让他们通过Facade进行通讯,从而简化了他们之间的依赖性。 第六节:实现:门面模式17 需求分析: 我们会发现中间者Mediator作为中心的周转站,其他的协作类都是通过中间者进行通信,因此中间者模式是一种行为模式。 中间者中引用了所有协作类,或者子模块(UndoRedo模块,状态机模块,输入输出模块,图元显示模块),因此导致子模块众多。使用者需要了解各个模块之间的协作关系。 我们让中间者又充当门面的角色(CFacadeMediator),让一系列复杂的类包装成一个简单的封闭接口。 这意味着所有的重要功能都通过CFacadeMediator类来进行操作,不要使用子模块的接口函数,而是将子模
14、块的接口函数都封装在CFacadeMediator类中,这样即使再多再复杂的子模块,我们都把他们隐藏起来,你不需要调用子模块的相关函数,而是调用CFacadeMediator中的封装的相关接口函数。这样就避免了过多类协作,使用起来很复杂的状况。 由此可见,门面模式是一种结构模式,将系统中的复杂的类协作关系扁平化。 第六节:实现:门面模式18 第七节:实现:职责链模式19意图: 使多个对象有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这 条链传递该请求,直到有一个对象处理它为止。 用途: 1、有多个的对象可以处理一个请求,哪个对象处理该请求由运行时刻自动
15、确定。 2、你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可以处理一个请求的对象集合应该被动态指定。第七节:实现:职责链模式20 需求分析: 当我们按下F1键时,当前获得焦点的控件会接受到F1键盘事件,弹出一个MsgBox对话框,显示当前控件的用途帮助信息。 最简单的方法是监听每个控件的F1键盘事件,作出响应。但是代码分散到了各个控件的事件响应实现中。而且如果我们要调整某些控件不提供帮助,而有些提供,意味着帮助系统是可配置的。在这种情况下,我们需要更灵活的机制。而职责链特别适合这种情形。CControlHelpChain代表一个职责链,通过next指针形成链表。每一个CControl HelpChain有一个指针指向CControlBase。CControlHelpChain有一个静态的成员函数用于监听CControlBase的F1键盘事件,在CControlHelpChain的构造函数中,将该静态成员监听函数注册到其所指向的CControlBase中。 使用静态成
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 许疃矿7煤层周期来压步距预测方法的研究
- 基于主动配液的非共沸工质蓄热热泵系统研究
- 2025福建莆田学院招聘博士高层次人才82人(二)备考考试题库附答案解析
- 基于全生命周期视角的绿色建筑成本效益分析研究
- 张家口市人民医院消化内科英语查房能力考核标准
- 运城市人民医院运动诱发电位考核
- 晋中市中医院医疗质量改进考核
- 融合多源异构数据的上市公司财务欺诈识别研究
- 基于观测数据的隐变量因果结构学习算法研究
- 2025年新修订建筑工程施工合同协议
- 2025中国银行考试试题及答案
- 分拣标准化培训课件
- 2025至2030中国电容膜片真空计行业项目调研及市场前景预测评估报告
- 女装秋冬商品培训
- 2025年新团员入团考试试题及答案
- 第2课《中国人首次进入自己的空间站》课件-2025-2026学年统编版语文八年级上册
- 2025年安全教育平台登录入口与模拟试题集
- 公司注销原合同补充协议
- 2025-2030中国区块链技术在供应链金融中的信用穿透效应
- 护理学用药安全知识培训课件
- 2025年《铁道概论》考试复习题库(含答案)
评论
0/150
提交评论