第4章 结构型模式
- 格式:pdf
- 大小:2.20 MB
- 文档页数:56
第4章结构型模式实训4.3 实训练习4.3.1 选择题1. 某公司开发一个文档编辑器,该编辑器允许在文档中直接嵌入图形对象,但开销很大。
用户在系统设计之初提出编辑器在打开文档时必须十分迅速,可以暂时通过一些符号来表示相应的图形。
针对这种需求,公司可以采用( )避免同时创建这些图形对象。
A. 代理模式B. 外观模式C. 桥接模式D. 组合模式2. 下面的( )模式将对象组合成树形结构以表示“部分-整体”的层次结构,并使得用户对单个对象和组合对象的使用具有一致性。
A. 组合 (Composite)B. 桥接 (Bridge)C. 装饰 (Decorator)D. 外观 (Facade)3. 已知某子系统为外界提供功能服务,但该子系统中存在很多粒度十分小的类,不便被外界系统直接使用,采用( )设计模式可以定义一个高层接口,这个接口使得这一子系统更加容易使用。
A. Facade(外观)B. Singleton(单例)C. Participant(参与者)D. Decorator(装饰)4. 当不能采用生成子类的方法进行扩充时,可采用( )设计模式动态地给一个对象添加一些额外的职责。
A. Facade(外观)B. Singleton(单例)C. Participant(参与者)D. Decorator(装饰)5. ( ① )设计模式将抽象部分与它的实现部分相分离,使它们都可以独立地变化。
下图为该设计模式的类图,其中,( ② )用于定义实现部分的接口。
① A. Singleton(单例) B. Bridge(桥接)C. Composite(组合)D. Facade(外观)② A. Abstraction B. ConcreteImplementorAC. ConcreteImplementorBD. Implementor6. ( ① )限制了创建类的实例数量,而( ② )将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
设计模式之Adapter(适配器)定义:将两个不兼容的类纠合在一起使用,属于结构型模式,需要有Adaptee(被适配者)和Adaptor(适配器)两个身份.为何使用?我们经常碰到要将两个没有关系的类组合在一起使用,第一解决方案是:修改各自类的接口,但是如果我们没有源代码,或者,我们不愿意为了一个应用而修改各自的接口。
怎么办?使用Adapter,在这两种接口之间创建一个混合接口(混血儿).如何使用?实现Adapter方式,其实"think in Java"的"类再生"一节中已经提到,有两种方式:组合(composition)和继承(inheritance).假设我们要打桩,有两种类:方形桩圆形桩.public class SquarePeg{public void insert(String str){System.out.println("SquarePeg insert():"+str);}}public class RoundPeg{public void insertIntohole(String msg){System.out.println("RoundPeg insertIntoHole():"+msg);}}现在有一个应用,需要既打方形桩,又打圆形桩.那么我们需要将这两个没有关系的类综合应用.假设RoundPeg我们没有源代码,或源代码我们不想修改,那么我们使用Adapter来实现这个应用:public class PegAdapter extends SquarePeg{private RoundPeg roundPeg;public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)public void insert(String str){ roundPeg.insertIntoHole(str);}}在上面代码中,RoundPeg属于Adaptee,是被适配者.PegAdapter是Adapter,将Adaptee(被适配者RoundPeg)和Target(目标SquarePeg)进行适配.实际上这是将组合方法(composition)和继承(inheritance)方法综合运用.PegAdapter首先继承SquarePeg,然后使用new的组合生成对象方式,生成RoundPeg的对象roundPeg,再重载父类insert()方法。
第二节系统结构模型化技术一、系统结构模型化基础(一)结构分析的概念与意义任何系统都是由两个以上有机联系、相互作用的要素所组成的,具有特定功能与结构的整体。
结构即组成系统诸要素之间相互关联的方式。
包括现代企业在内的大规模复杂系统具有要素及其层次众多、结构复杂与社会性突出等特点。
在研究与解决这类系统问题时,往往要通过建立系统的结构模型,进行系统的结构分析,以求得对问题全面与本质的认识。
结构模型是定性表示系统构成要素以及它们之间存在着的本质上相互依赖、相互制约与关联情况的模型。
结构模型化即建立系统结构模型的过程。
该过程注重表现系统要素之间相互作用的性质,是系统认识、准确把握复杂问题,并对问题建立数学模型、进行定量分析的基础。
阶层性是大规模复杂系统的基本特性,在结构模型化过程中,对递阶结构的研究是一项重要工作。
结构分析是一个实现系统结构模型化并加以解释的过程。
其具体内容包括:对系统目的--功能的认识;系统构成要素的选取;对要素间的联系及其层次关系的分析;系统整体结构的确定及其解释。
系统结构模型化是结构分析的基本内容。
结构分析是系统分析的重要内容,是系统优化分析、设计与管理的基础。
尤其是在分析与解决社会经济系统问题时,对系统结构的正确认识与描述更具有数学模型与定量分析所无法替代的作用。
(二)系统结构的基本表达方式系统的要素及其关系形成系统的特定结构。
在通常情况下,可采用集合、有向图与矩阵等三种相互对应的方式来表达系统的某种结构。
1、系统结构的集合表达设系统由n(n≥2)个要素(S1,S2,…,Sn)所组成,其集合为S,则有:S={S1,S2,…,Sn}系统的诸多要素有机地联系在一起,并且一般都是以两个要素之间的二元关系为基础的。
所谓二元关系是根据系统的性质与研究的目的所约定的一种需要讨论的、存在于系统中的两个要素(Si、Sj)之间的关系Rij(简记为R)。
通常有影响关系、因果关系、包含关系、隶属关系以及各种可以比较的关系(如大小、先后、轻重、优劣等)。
软件开发流程优化指南第1章引言 (3)1.1 软件开发流程概述 (3)1.2 流程优化的重要性 (4)1.3 本指南的目的与结构 (4)第2章需求分析与规划 (5)2.1 需求收集与梳理 (5)2.1.1 需求收集方法 (5)2.1.2 需求梳理 (5)2.2 需求分析与评估 (5)2.2.1 需求分析 (5)2.2.2 需求评估 (6)2.3 项目规划与目标设定 (6)2.3.1 项目规划 (6)2.3.2 目标设定 (6)第3章设计与架构 (6)3.1 系统架构设计 (6)3.1.1 架构风格选择 (6)3.1.2 架构层次划分 (7)3.1.3 系统组件定义 (7)3.1.4 功能优化 (7)3.2 组件与模块划分 (7)3.2.1 组件划分原则 (7)3.2.2 模块划分方法 (7)3.3 设计模式应用 (7)3.3.1 创建型模式 (7)3.3.2 结构型模式 (8)3.3.3 行为型模式 (8)3.3.4 设计模式选择 (8)第4章编码与实现 (8)4.1 编码规范与约定 (8)4.1.1 代码风格 (8)4.1.2 注释与文档 (8)4.1.3 代码组织 (8)4.2 代码质量保证 (8)4.2.1 单元测试 (9)4.2.2 代码审查 (9)4.2.3 代码规范检查 (9)4.3 代码审查与优化 (9)4.3.1 审查流程 (9)4.3.2 优化方向 (9)4.3.3 持续改进 (9)第5章测试策略与实施 (10)5.1 测试类型与方法 (10)5.1.1 单元测试 (10)5.1.2 集成测试 (10)5.1.3 系统测试 (10)5.1.4 验收测试 (10)5.2 测试计划与用例设计 (11)5.2.1 测试计划 (11)5.2.2 测试用例设计 (11)5.3 自动化测试与持续集成 (11)5.3.1 自动化测试 (11)5.3.2 持续集成 (11)第6章项目管理与团队协作 (12)6.1 项目进度管理 (12)6.1.1 进度计划编制 (12)6.1.2 进度监控与调整 (12)6.1.3 里程碑管理 (12)6.2 风险识别与应对 (12)6.2.1 风险识别 (12)6.2.2 风险评估 (12)6.2.3 风险应对 (12)6.3 团队沟通与协作 (12)6.3.1 沟通机制 (13)6.3.2 团队协作工具 (13)6.3.3 团队建设 (13)6.3.4 冲突管理 (13)第7章软件交付与部署 (13)7.1 软件打包与发布 (13)7.1.1 打包工具与规范 (13)7.1.2 打包流程 (13)7.1.3 发布策略 (13)7.2 部署策略与实施 (14)7.2.1 部署模式 (14)7.2.2 部署流程 (14)7.2.3 部署注意事项 (14)7.3 生产环境监控与优化 (14)7.3.1 监控策略 (14)7.3.2 优化措施 (14)7.3.3 应急响应 (15)第8章用户培训与支持 (15)8.1 培训内容与方法 (15)8.1.1 培训内容 (15)8.1.2 培训方法 (15)8.2 用户支持与问题解决 (15)8.2.1 用户支持 (16)8.2.2 问题解决 (16)8.3 用户反馈与需求跟进 (16)8.3.1 用户反馈 (16)8.3.2 需求跟进 (16)第9章软件维护与更新 (16)9.1 软件维护策略 (16)9.1.1 维护目标与原则 (16)9.1.2 维护类型与周期 (17)9.1.3 维护团队与职责 (17)9.2 问题诊断与修复 (17)9.2.1 问题识别 (17)9.2.2 问题分析与定位 (17)9.2.3 问题修复与验证 (17)9.3 版本更新与兼容性 (17)9.3.1 版本规划与管理 (17)9.3.2 兼容性测试与评估 (18)9.3.3 更新策略与实施 (18)9.3.4 更新记录与文档 (18)第10章持续改进与创新 (18)10.1 流程优化方法 (18)10.1.1 流程审计与评估 (18)10.1.2 设定明确的目标 (18)10.1.3 采用敏捷方法 (18)10.1.4 激励团队参与 (18)10.1.5 建立持续改进机制 (18)10.2 技术创新与实践 (19)10.2.1 技术研究与创新 (19)10.2.2 技术分享与交流 (19)10.2.3 试点项目 (19)10.2.4 建立技术储备库 (19)10.3 适应变化与未来发展 (19)10.3.1 市场趋势分析 (19)10.3.2 客户需求挖掘 (19)10.3.3 灵活调整流程 (19)10.3.4 培养团队适应性 (19)第1章引言1.1 软件开发流程概述软件开发流程是软件企业在开发软件产品过程中遵循的一种规范化的工作方法。
第4章结构型模式结构型模式涉及到如何组合类和对象以获得更大的结构。
结构型类模式采用继承机制来组合接口或实现。
一个简单的例子是采用多重继承方法将两个以上的类组合成一个类,结果这个类包含了所有父类的性质。
这一模式尤其有助于多个独立开发的类库协同工作。
另外一个例子是类形式的A d a p t e r(4.1)模式。
一般来说,适配器使得一个接口( a d a p t e e的接口)与其他接口兼容,从而给出了多个不同接口的统一抽象。
为此,类适配器对一个 a d a p t e e类进行私有继承。
这样,适配器就可以用a d a p t e e的接口表示它的接口。
结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法。
因为可以在运行时刻改变对象组合关系,所以对象组合方式具有更大的灵活性,而这种机制用静态类组合是不可能实现的。
Composite (4.3) 模式是结构型对象模式的一个实例。
它描述了如何构造一个类层次式结构,这一结构由两种类型的对象(基元对象和组合对象)所对应的类构成. 其中的组合对象使得你可以组合基元对象以及其他的组合对象,从而形成任意复杂的结构。
在Proxy (4.7) 模式中,p r o x y对象作为其他对象的一个方便的替代或占位符。
它的使用可以有多种形式。
例如它可以在局部空间中代表一个远程地址空间中的对象,也可以表示一个要求被加载的较大的对象,还可以用来保护对敏感对象的访问。
P r o x y模式还提供了对对象的一些特有性质的一定程度上的间接访问,从而它可以限制、增强或修改这些性质。
F l y w e i g h t(4.6)模式为了共享对象定义了一个结构。
至少有两个原因要求对象共享:效率和一致性。
F l y w e i g h t的对象共享机制主要强调对象的空间效率。
使用很多对象的应用必需考虑每一个对象的开销。
使用对象共享而不是进行对象复制,可以节省大量的空间资源。
但是仅当这些对象没有定义与上下文相关的状态时,它们才可以被共享。
F l y w e i g h t的对象没有这样的状态。
任何执行任务时需要的其他一些信息仅当需要时才传递过去。
由于不存在与上下文相关的状态,因此F l y w e i g h t对象可以被自由地共享。
如果说F l y w e i g h t模式说明了如何生成很多较小的对象,那么F a c a d e(4.5)模式则描述了如何用单个对象表示整个子系统。
模式中的f a c a d e用来表示一组对象,f a c a d e的职责是将消息转发给它所表示的对象。
B r i d g e(4.2)模式将对象的抽象和其实现分离,从而可以独立地改变它们。
D e c o r a t o r(4.4)模式描述了如何动态地为对象添加职责。
D e c o r a t o r模式是一种结构型模式。
这一模式采用递归方式组合对象,从而允许你添加任意多的对象职责。
例如,一个包含用户界面组件的D e c o r a t o r对象可以将边框或阴影这样的装饰添加到该组件中,或者它可以将窗口滚动和缩放这样的功能添加的组件中。
我们可以将一个D e c o r a t o r对象嵌套在另外一个对象中就可以很简单地增加两个装饰,添加其他的装饰也是如此。
因此,每个 D e c o r a t o r对象必须与其组件的接口兼容并且保证将消息传递给它。
D e c o r a t o r模式在转发一条信息之前或之后都可以完成它的工作(比如绘制组件的边框)。
许多结构型模式在某种程度上具有相关性,我们将在本章末讨论这些关系。
4.1 ADAPTER (适配器)—类对象结构型模式1. 意图将一个类的接口转换成客户希望的另外一个接口。
A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
2. 别名包装器Wr a p p e r 。
3. 动机有时,为复用而设计的工具箱类不能够被复用的原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配。
例如,有一个绘图编辑器,这个编辑器允许用户绘制和排列基本图元(线、多边型和正文等)生成图片和图表。
这个绘图编辑器的关键抽象是图形对象。
图形对象有一个可编辑的形状,并可以绘制自身。
图形对象的接口由一个称为S h a p e 的抽象类定义。
绘图编辑器为每一种图形对象定义了一个S h a p e 的子类:L i n e S h a p e 类对应于直线,P o l y g o n S h a p e 类对应于多边型,等等。
像L i n e S h a p e 和P o l y g o n S h a p e 这样的基本几何图形的类比较容易实现,这是由于它们的绘图和编辑功能本来就很有限。
但是对于可以显示和编辑正文的Te x t S h a p e 子类来说,实现相当困难,因为即使是基本的正文编辑也要涉及到复杂的屏幕刷新和缓冲区管理。
同时,成品的用户界面工具箱可能已经提供了一个复杂的Te x t V i e w 类用于显示和编辑正文。
理想的情况是我们可以复用这个Te x t V i e w 类以实现Te x t S h a p e 类,但是工具箱的设计者当时并没有考虑S h a p e 的存在,因此Te x t V i e w 和S h a p e 对象不能互换。
一个应用可能会有一些类具有不同的接口并且这些接口互不兼容,在这样的应用中象Te x t V i e w 这样已经存在并且不相关的类如何协同工作呢?我们可以改变Te x t V i e w 类使它兼容S h a p e 类的接口,但前提是必须有这个工具箱的源代码。
然而即使我们得到了这些源代码,修改Te x t V i e w也是没有什么意义的;因为不应该仅仅为了实现一个应用,工具箱就不得不采用一些与特定领域相关的接口。
我们可以不用上面的方法,而定义一个Te x t S h a p e 类,由它来适配Te x t V i e w 的接口和S h a p e 的接口。
我们可以用两种方法做这件事:1) 继承S h a p e 类的接口和Te x t V i e w 的实现,或2) 将一个Te x t V i e w 实例作为Te x t S h a p e 的组成部分,并且使用Te x t V i e w 的接口实现Te x t S h a p e 方法恰恰对应于A d a p t e r 模式的类和对象版本。
我们将Te x t S h a p e 称之为适配器A d a p t e r 。
被转换成在Te x t V i e w类中定义的G e t E x t e n t请求。
由于Te x t S h a p e将Te x t V i e w的接口与S h a p e的接口进行了匹配,因此绘图编辑器就可以复用原先并不兼容的Te x t V i e w类。
A d a p t e r时常还要负责提供那些被匹配的类所没有提供的功能,上面的类图中说明了适配器如何实现这些职责。
由于绘图编辑器允许用户交互的将每一个S h a p e对象“拖动”到一个新的位置,而Te x t V i e w设计中没有这种功能。
我们可以实现Te x t S h a p e类的C r e a t e M a n i p u l a t o r操作,从而增加这个缺少的功能,这个操作返回相应的M a n i p u l a t o r子类的一个实例。
M a n i p u l a t o r是一个抽象类,它所描述的对象知道如何驱动S h a p e类响应相应的用户输入,例如将图形拖动到一个新的位置。
对应于不同形状的图形,M a n i p u l a t o r有不同的子类;例如子类Te x t M a n i p u l a t o r对应于Te x t S h a p e。
Te x t S h a p e通过返回一个Te x t M a n i p u l a t o r实例,增加了Te x t V i e w中缺少而S h a p e需要的功能。
4. 适用性以下情况使用A d a p t e r模式• 你想使用一个已经存在的类,而它的接口不符合你的需求。
• 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
• (仅适用于对象A d a p t e r)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。
对象适配器可以适配它的父类接口。
5. 结构对象匹配器依赖于对象组合,如下图所示。
6. 参与者• Ta r g e t( S h a p e)—定义C l i e n t使用的与特定领域相关的接口。
• C l i e n t( D r a w i n g E d i t o r)—与符合Ta r g e t接口的对象协同。
• A d a p t e e( T e x t V i e w)—定义一个已经存在的接口,这个接口需要适配。
• A d a p t e r( T e x t S h a p e)—对A d a p t e e的接口与Ta r g e t接口进行适配7. 协作• Client在A d a p t e r实例上调用一些操作。
接着适配器调用A d a p t e e的操作实现这个请求。
8. 效果类适配器和对象适配器有不同的权衡。
类适配器• 用一个具体的A d a p t e r类对A d a p t e e和Ta r g e t进行匹配。
结果是当我们想要匹配一个类以及所有它的子类时,类A d a p t e r将不能胜任工作。
• 使得A d a p t e r可以重定义A d a p t e e的部分行为,因为A d a p t e r是A d a p t e e的一个子类。
• 仅仅引入了一个对象,并不需要额外的指针以间接得到a d a p t e e。
对象适配器则• 允许一个A d a p t e r与多个A d a p t e e—即A d a p t e e本身以及它的所有子类(如果有子类的话)—同时工作。
A d a p t e r也可以一次给所有的A d a p t e e添加功能。
• 使得重定义A d a p t e e的行为比较困难。
这就需要生成A d a p t e e的子类并且使得A d a p t e r引用这个子类而不是引用A d a p t e e本身。
使用A d a p t e r模式时需要考虑的其他一些因素有:1) Adapter的匹配程度对A d a p t e e的接口与Ta r g e t的接口进行匹配的工作量各个A d a p t e r可能不一样。