版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1温故知新(wēngùzhīxīn)设计模式概念设计模式的描述实例研究:文档编辑器LexiLexi的文档结构(jiégòu)与组合(Composite)模式共四十五页2软件体系结构
第9讲:设计模式(二)江贺共四十五页3内容简介:Lexi的格式化与策略(cèlüè)(Strategy)模式Lexi的修饰用户界面与修饰(Decorator)模式共四十五页4Lexi的格式化与策略(cèlüè)(Strategy)模式Lexi的格式化:Lexi是如何来创建数据结构的?那些对象负责(fùzé)不同的格式化策略?栏行共四十五页5Lexi的格式化与策略(cèlüè)(Strategy)模式在第9讲里面,我们已经按照组合模式设计存储各种图元的类。问题是如何把基本(jīběn)图元划分成为组合图元。比如,一行里面包含多少个字符,包含哪些字符、图像?图元共四十五页6Lexi的格式化与策略(cèlüè)(Strategy)模式这里(zhèlǐ),我们简化考虑,只考虑如何把字符、图像这样的划分成为行的操作;如何把行划分成为栏,如何把栏划分成为页,与行的划分基本思想相同。把字符、图像这样的基本图元划分成为行可以有不同的算法:速度最快、效果最差Simple速度中等、效果一般Array速度最慢、效果最好TeX共四十五页7Lexi的格式化与策略(cèlüè)(Strategy)模式传统实现方法:把这些不同的算法(suànfǎ)都放到图元类中,作为图元类的方法。优点:封装好,方法和属性在一起。缺点:灵活性差,GlyphDraw()Insert(..)InterSects(..)Simple()Array()Tex()共四十五页8Lexi的格式化与策略(cèlüè)(Strategy)模式策略(cèlüè)模式解决Lexi的格式化问题:考虑到以下因素:不同算法的接口基本一致不同算法的功能基本相同解决方案:把算法封装到类中不同算法的基类相同,利用基类对外提供统一的接口共四十五页9Lexi的格式化与策略(cèlüè)(Strategy)模式基类,封装了各种(ɡèzhǒnɡ)算法的公共接口具体算法类共四十五页10Lexi的格式化与策略(cèlüè)(Strategy)模式共四十五页11Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式意图定义(dìngyì)一系列的算法,把它们一个个封装起来,并且使它们可以可以相互替换。本模式使得算法可以独立于使用它的客户而变化。别名政策(Policy)共四十五页12Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式动机有许多算法可以对一个(yīɡè)文本流进行分行。将这些算法硬性地放入到使用它们的类中是不可取的:需要换行功能的客户程序如果直接包含换行算法代码,自身将变得更加复杂,使得客户程序庞大而难以维护,特别是在需要支持多种换行算法的时候不同的时候需要不同的算法,我们不想支持并不使用的那些换行算法当换行算法是客户程序的一部分时,增加新的换行算法或改变现有算法将十分困难共四十五页13Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式动机为了解决这些困难(kùnnɑn),可以定义一些类来封装不同的换行算法。一种以这种方法封装的算法称为一个策略(strategy)共四十五页14Lexi的格式化与策略(cèlüè)(Strategy)模式策略(cèlüè)模式代码示例Composition代码:classComposition{ public: Composition(Compositor*);voidRepair();private:
Compositor*_compositor;Component*_components;//thelistofcomponentsint_componentCount;//thenumberofcomponentsint_lineWidth;//theComposition'slinewidthint*_lineBreaks;//thepositionoflinebreaksincomponentsint_lineCount;//thenumberoflines};
共四十五页15Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式(móshì)代码示例Compositor代码:classCompositor{ public: virtualintCompose(Coordnatural[],Coordstretch[], Coordshrink[],intcomponentCount, intlineWidth,intbreaks[])=0; protected:Compositor();};
共四十五页16Lexi的格式化与策略(cèlüè)(Strategy)模式策略(cèlüè)模式代码示例Compositon类的repair函数代码:voidComposition::Repair(){Coord*natural;Coord*stretchability;Coord*shrinkability;intcomponentCount;int*breaks;//preparethearrayswiththedesiredcomponentsizes//...//determinewherethebreaksare:intbreakCount;breakCount=_compositor->Compose(natural,stretchability,shrinkability,componentCount,_lineWidth,breaks);//layoutcomponentsaccordingtobreaks//...}
共四十五页17Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式代码(dàimǎ)示例SimpleCompositor类的代码:classSimpleCompositor:publicCompositor{public:SimpleCompositor();virtualintCompose(Coordnatural[],Coordstretch[],Coordshrink[],intcomponentCount,intlineWidth,intbreaks[]);//...};
共四十五页18Lexi的格式化与策略(cèlüè)(Strategy)模式策略(cèlüè)模式代码示例TeXCompositor类的代码:classTeXCompositor:publicCompositor{ public:TeXCompositor(); virtualintCompose(Coordnatural[],Coordstretch[],Coord shrink[],intcomponentCount,intlineWidth,intbreaks[]); //... };
共四十五页19Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式代码(dàimǎ)示例ArrayCompositor类的代码:classArrayCompositor:publicCompositor{ public:ArrayCompositor(intinterval); virtualintCompose(Coordnatural[],Coordstretch[],Coord shrink[],intcomponentCount,intlineWidth,intbreaks[]); //... };
共四十五页20Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式(móshì)代码示例Composition*quick=newComposition(newSimpleCompositor);Composition*slick=newComposition(newTeXCompositor);Composition*iconic=newComposition(newArrayCompositor(100));
共四十五页21Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式适用性许多相关类仅仅是行为有异。需要使用一个算法的不同变体。算法使用客户不应该知道的数据。一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件(tiáojiàn)语句的形式出现。将相关的条件(tiáojiàn)分支移入它们各自的Strategy类中以代替这些条件语句。共四十五页22Lexi的格式化与策略(cèlüè)(Strategy)模式策略(cèlüè)模式结构共四十五页23Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式参与者Strategy(策略,如Compositor)定义所有支持的算法的公共接口。Context使用(shǐyòng)这个接口来调用某个ConcreteStrategy定义的算法。ConcreteStrategy(具体策略,如SimpleCompositor,TeXCompositor等)以Strategy接口实现某个具体算法Context(上下文,如Composition)用一个ConcreteStrategy对象来配置维护一个对Strategy对象的引用可以定一个接口,允许Strategy访问它的数据共四十五页24Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式协作Strategy和Context相互作用以实现选定的算法。当算法被调用时,Context可以将该算法所需要的所有数据(shùjù)都传递给该Strategy。或者,Context可以将自身作为一个参数传递给Strategy操作。Context将它的客户请求转发给它的Strategy。客户通常创建并传递一个ConcreteStrategy对象给该Context;这样,客户仅仅与Context交互。通常,有一系列的ConcreteStrategy类可以供客户从中选择。共四十五页25Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式效果相关算法(suànfǎ)系列Strategy类层次为Context定义了一系列可供重用的算法或行为。消除了一些条件语句不用Strategy,Context中正文换行可能使用如下代码voidComposition::Repair(){switch(_breakingStrategy){caseSimpleStrategy:ComposeWithSimpleCompositor();break;caseTeXStrategy:ComposeWithTeXCompositor();break;//...}}voidComposition::Repair(){_compositor->Compose();}共四十五页26Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式效果实现的选择Strategy模式提供了相同行为(xíngwéi)的不同实现。客户可以根据不同时间/空间权衡取舍要求从不同策略中进行选择。客户必须了解不同的StrategyStrategy和Context之间的通信开销增加了对象和类的数目共四十五页27Lexi的格式化与策略(cèlüè)(Strategy)模式策略模式实现定义Strategy和Context接口,Strategy和Context接口必须(bìxū)使得ConcreteStrategy能够有效地访问它所需要的Context中的任何数据,反之亦然。一种方法是让Context将数据放在参数中传递给Strategy,另外一种方法是将Context自身(引用)作为一个参数传递给Strategy.共四十五页28Lexi的修饰用户界面(yònɡhùjièmiàn)与修饰(Decorator)模式修饰(xiūshì)用户界面:Lexi的用户界面包括滚动条、边界。共四十五页29Lexi的修饰用户界面(yònɡhùjièmiàn)与修饰(Decorator)模式传统做法:为Composition类创建(chuàngjiàn)一个子类BorderedCompositon,用来给Composition添加边界;创建ScrollableComposition来增加滚动条;创建BorderedScrollableComposition来支持滚动条和边界。
随着界面的增加,导致类爆炸共四十五页30Lexi的修饰用户界面(yònɡhùjièmiàn)与修饰(Decorator)模式修饰模式解决修饰用户界面(yònɡhùjièmiàn)问题:考虑到以下因素:Scrollbar和Border的主要动作是draw,也就是接口基本一样解决方案:Scrollbar和Border继承同样一个基类MonoGlyph,MonoGlyph继承Glyph,同时包含成员变量,该成员变量是MonoGlyph除自身外还要绘制的对象。例如,Border类除了绘制一个边界,它还负责绘制文本页。这样就形成了边界包围在文本之外的效果,文本的绘制由Border类调用文本对应的组合对象的相应方法来实现。共四十五页31Lexi的修饰(xiūshì)用户界面与修饰(xiūshì)(Decorator)模式voidMonoGlyph::Draw(Window*w){_component->Draw(w);}voidBorder::Draw(Window*w){MonoGlyph::Draw(w);DrawBorder(w);}共四十五页32border中有一个(yīɡè)成员变量scrollbar,border的绘制时调用scrollbar的绘制方法scrollbar中有一个成员(chéngyuán)变量composition,scrollbar的绘制时调用compositon的绘制方法共四十五页33Lexi的修饰(xiūshì)用户界面与修饰(xiūshì)(Decorator)模式修饰模式意图(yìtú)动态地给一个对象添加一些额外的操作,就增加功能来说,Decorator模式相比生成子类更为灵活。别名包装器Wrapper共四十五页34Lexi的修饰(xiūshì)用户界面与修饰(xiūshì)(Decorator)模式修饰模式动机类似(lèisì)于Lexi中给文本添加用户界面共四十五页35Lexi的修饰(xiūshì)用户界面与修饰(xiūshì)(Decorator)模式修饰模式(móshì)动机共四十五页36Lexi的修饰用户界面(yònɡhùjièmiàn)与修饰(Decorator)模式修饰模式代码(dàimǎ)示例VisualComponent类:classVisualComponent{ public:VisualComponent(); virtualvoidDraw(); virtualvoidResize(); //...};
共四十五页37Lexi的修饰(xiūshì)用户界面与修饰(xiūshì)(Decorator)模式修饰模式(móshì)代码示例Decorator类:classDecorator:publicVisualComponent{ public:Decorator(VisualComponent*); virtualvoidDraw(); virtualvoidResize(); //... private: VisualComponent*_component; };
共四十五页38Lexi的修饰用户界面(yònɡhùjièmiàn)与修饰(Decorator)模式修饰模式代码(dàimǎ)示例Decorator类中Draw和Resize的实现:voidDecorator::Draw(){ _component->Draw(); } voidDecorator::Resize(){ _component->Resize(); }
共四十五页39Lexi的修饰用户界面(yònɡhùjièmiàn)与修饰(Decorator)模式修饰模式(móshì)代码示例BorderDecorator类及Draw的实现:classBorderDecorator:publicDecorator{ public: BorderDecorator(VisualComponent*,intborderWidth); virtualvoidDraw(); private: voidDrawBorder(int); private: int_width; }; voidBorderDecorator::Draw(){ Decorator::Draw(); DrawBorder(_width); }
共四十五页40Lexi的修饰(xiūshì)用户界面与修饰(xiūshì)(Decorator)模式修饰模式代码示例如何使用D
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 型2024年度泵车租赁协议样本
- 全新服装加工合作协议合同范本下载
- 农业苗木采购合同范例
- 绿色基地建设合同范例
- 2024年度二手房交易定金支付条件协议3篇
- 租房简易合同范例
- 设计部合同范本
- 税所要业务合同范例
- 船东对船员合同范例
- 特色商品定制合同范例
- 12千伏环网柜(箱)标准化设计定制方案(2019版)
- 医院装修工程量清单
- 最新四川省教师资格认定体检表.docx
- 永磁电动机使用说明书胜利顺天
- 球形网架结构的吊顶施工做法
- 孟母三迁(课堂PPT)
- 人教版八年级数学上册14.3.2《公式法》第2课时 教 案
- 股东会同意借款决议范本专业版
- 《南州六月荔枝丹》学习要点
- 九年义务教育全日制小学音乐教学器材配备目录
- MSDS(10-100048)聚脂烤漆
评论
0/150
提交评论