《设计模式2.ppt》由会员分享,可在线阅读,更多相关《设计模式2.ppt(79页珍藏版)》请在三一文库上搜索。
1、设计模式(2),Design Pattern (2),2019/5/5,Institute of Computer Software Nanjing University,1,摘要,Design Patterns Why, What, How Creational, Structural and Behavioral Patterns,2019/5/5,Institute of Computer Software Nanjing University,2,Structural Patterns,结构模式描述如何将类或者对象结合在一起形成更大的结构。 类的结构模式:结构型类模式使用继承机制来组合
2、接口或实现。 对象的结构模式:结构型对象模式描述了如何对一些对象进行组合,从而实现新功能的一些方法。可以在运行时刻改变对象组合关系。,2019/5/5,Institute of Computer Software Nanjing University,3,Structural Patterns,Adapter Bridge Composite Decorator Facade Flyweight Proxy,2019/5/5,Institute of Computer Software Nanjing University,4,Adapter,Aliases:Wrapper Intent 将一
3、个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 Motivation 有时为复用而设计的工具箱类不能够被复用的原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配,2019/5/5,Institute of Computer Software Nanjing University,5,Example,2019/5/5,Institute of Computer Software Nanjing University,6,adapter,adaptee,target,Applicability,Use the Adapter
4、pattern when 你想使用一个已经存在的类,而它的接口不符合你的需求。 你想创建一个可以复用的类,该类可以与其它不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。 (仅适用于对象Adapter)你想使用一些已经存在的类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。,2019/5/5,Institute of Computer Software Nanjing University,7,Structure,2019/5/5,Institute of Computer Software Nanjing University,8,类适配器,
5、对象适配器,Participants,Target 定义Client使用的与特定领域相关的接口 Client 与符合Target接口的对象协同 Adaptee 定义一个已经存在的接口,这个接口需要适配 Adapter 对Adaptee的接口与Target的接口进行适配,2019/5/5,Institute of Computer Software Nanjing University,9,Collaboration,Client在Adapter实例上调用一些操作,接着适配器调用Adaptee的操作实现这个请求。,2019/5/5,Institute of Computer Software N
6、anjing University,10,Sample Code,Consequences,本质上是两种重用模型 class adapter: 无法适配adaptee以及所有它的子类,但是可以重载adaptee的行为 object adapter 可以适配adaptee的所有子类,但重定义adaptee的行为比较困难 Adapter的匹配精度:Adapter的工作量取决于Target接口与Adaptee接口的相似程度 Pluggable Adapters:具有内部接口适配的类,2019/5/5,Institute of Computer Software Nanjing University,
7、11,Consequences,使用双向适配器提供透明操作 针对class adapter,用多重继承来实现,2019/5/5,Institute of Computer Software Nanjing University,12,Implementation,使用继承机制实现class adapter 使用内嵌对象技术实现object adapter Pluggable Adapters 使用抽象操作 使用代理对象 参数化的适配器:reflection技术,2019/5/5,Institute of Computer Software Nanjing University,13,Relat
8、ed Patterns,Bridge:结构类似,但Bridge的目的是将接口部分和实现部分分离,从而使得它们可以较为容易也相对独立的加以改变。而adapter则意味着改变一个已有对象的接口 Decorator:增强了其它对象的功能而同时又不改变它的接口,透明性比adapter好 Proxy:在不改变它的接口的条件下,为另一个对象定义了一个代理。,2019/5/5,Institute of Computer Software Nanjing University,14,增:Default Adapter,适配器模式的特例! 缺省适配模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展
9、,而不必从原有接口扩展。 Motivation Java中有着特殊的应用 java.awt.event.WindowAdapter,2019/5/5,Institute of Computer Software Nanjing University,15,Example,interface 和尚 public void 吃斋(); public void 念经(); public void 打坐(); public void 撞钟(); public void 习武(); public String getName(); ,2019/5/5,Institute of Computer Soft
10、ware Nanjing University,16,class 鲁智深 implements 和尚 public void 习武() 拳打镇关西;大闹五台山; public String getName() return “鲁智深”; ,Compilation Error!,abstract class 天星 implements和尚 public void 吃斋(); public void 念经(); public void 打坐(); public void 撞钟(); public void 习武(); public String getName()return null; ,cla
11、ss 鲁智深 extends 天星 public void 习武() 拳打镇关西;大闹五台山; public String getName() return “鲁智深”; ,Compilation Passed!,Adapter!,Applicability,如果不准备实现一个接口的所有方法时,可以制造一个抽象类,给出所有方法的平庸的具体实现 适配器模式把一个类的接口变换成客户端所期待的另一种接口,适配器模式的“平庸化”形式可以使所考察的类不必实现不需要的那部分接口。,2019/5/5,Institute of Computer Software Nanjing University,17,S
12、tructure,2019/5/5,Institute of Computer Software Nanjing University,18,ServiceAdapter应当是抽象类,但它所提供的方法却应当是具体的方法,而不是抽象的方法提供默认实现。 具体子类可以按照需要只实现需要实现的方法,忽略不需要实现的方法。,Sample Code,Bridge,Aliases:Handle/Body Intent 将抽象部分与它的实现部分分离,使它们都可以独立地变化 Motivation 要做到“抽象(接口)与实现分离”,最常用的办法是定义一个抽象类,然后在子类中提供实现。也就是说,用继承机制达到“抽
13、象(接口)与实现分离” 但是这种方法不够灵活,继承机制把实现与抽象部分永久地绑定起来,要想独立地修改、扩展、重用抽象(接口)与实现都非常困难。 回顾下OCP和CARP原则,2019/5/5,Institute of Computer Software Nanjing University,19,Example,2019/5/5,Institute of Computer Software Nanjing University,20,扩展Window抽象使之用于不同种类的窗口或新的平台很不方便,继承机制使得客户代码与平台相关,Example,2019/5/5,Institute of Compu
14、ter Software Nanjing University,21,将Window抽象和它的实现部分分别放在独立的类层次结构中,针对窗口接口,针对平台的窗口实现,对“变化”的封装,2019/5/5,Institute of Computer Software Nanjing University,22,抽象化,实现化,Abstraction,Implementation,需要变化,需要变化,Bridge!,Applicability,编译时刻无法确定抽象(接口)与实现之间的关系 抽象部分与实现部分都可以通过子类化而扩展 对一个实现的修改不影响客户(无须重新编译) 在C+中,对客户完全隐瞒实现
15、细节 因为扩展的原因,需要把一个类分成两部分,(以便灵活组合) 在多个对象之间共享数据,但客户不需要知道,2019/5/5,Institute of Computer Software Nanjing University,23,Structure,2019/5/5,Institute of Computer Software Nanjing University,24,Participants,Abstraction 定义抽象类的接口 维护一个指向Implementor类型对象的指针 RefinedAbstraction 扩充由Abstraction定义的接口 Implementor 定义实
16、现类的接口,不一定要与Abstraction的接口完全一致,甚至可以完全不同 ConcreteImplementor 实现Implementor接口并定义它的具体实现,2019/5/5,Institute of Computer Software Nanjing University,25,Collaborations,Abstraction将Client的请求转发给它的Implementor对象,2019/5/5,Institute of Computer Software Nanjing University,26,Sample Code,Consequences,分离接口及其实现部分。抽
17、象类的实现可以在运行时刻进行配置,一个对象甚至可以在运行时刻改变它的实现 提高可扩充性:抽象与实现两部分可以单独扩充 实现细节对客户透明,2019/5/5,Institute of Computer Software Nanjing University,27,Implementation,仅有一个Implementor则没有必要创建一个抽象的Implementor - 退化 创建正确的Implementor对象 根据客户环境,或者通过factory (回顾Abstract Factory) 共享implementors 资源管理:引用计数技术 采用多继承机制,依赖于静态继承, 不好,2019
18、/5/5,Institute of Computer Software Nanjing University,28,Related Patterns,Abstract Factory可以用来创建和配置Bridge模式 与Adapter模式的区别 Adapter模式用来帮助无关的类协同工作,通常在系统设计完成后才会被使用 Bridge模式则在系统开始时就被使用,它使得抽象接口和实现部分可以独立进行改变,2019/5/5,Institute of Computer Software Nanjing University,29,思考题:JDBC/ODBC桥梁是Bridge模式吗?,Composite
19、,Intent 将对象组合成树形结构以表示“部分-整体”的层次结构,Composite使得用户对单个对象和组合对象的使用具有一致性。 Motivation 一些部件对象经过组合构成的复合部件对象仍然具有单个部件对象的接口,这样的复合部件对象被称为“容器(container)” 复合部件与单个部件具有同样的接口,所有接口包含两部分:单个部件的功能、管理子部件的功能 递归组合,2019/5/5,Institute of Computer Software Nanjing University,30,Example,2019/5/5,Institute of Computer Software Na
20、njing University,31,Applicability,想表示对象的“部分-整体”层次结构 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象,2019/5/5,Institute of Computer Software Nanjing University,32,Structure,2019/5/5,Institute of Computer Software Nanjing University,33,Participants,Component 为组合中的对象声明接口 在适当的情况下实现所有类共有接口的缺省行为 声明一个接口用于访问和管理Compon
21、ent的子组件 (可选)在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。 Leaf 在组合中表示叶节点对象,没有子节点 在组合中定义图元对象的行为 Composite 定义有子部件的那些部件的行为 存储子部件 在Component接口中实现与子部件有关的操作 Client 通过Component接口操纵组合部件的对象,2019/5/5,Institute of Computer Software Nanjing University,34,Collaborations,用户使用Component类接口与组合结构中的对象进行交互。如果接收者是一个叶节点,则直接处理请求。如果
22、接收者是Composite,它通常将请求发送给它的子部件,在转发请求之前与/或之后可能执行一些辅助操作。,2019/5/5,Institute of Computer Software Nanjing University,35,Sample Code,Consequences,定义了包含leaf对象和composite对象的类层次接口。 递归结构 简化客户代码,客户一致地处理复合对象和单个对象 使得更容易增加新类型的组件,易于增加新类型的组件 使设计变得更加一般化,无法限制类型的组合,可以在运行时刻通过类型检查加以弥补,2019/5/5,Institute of Computer Softw
23、are Nanjing University,36,Implementation,显式的父对象的引用,在子对象中给出父对象的引用,可以很容易地遍历所有的父对象 共享组件:当一个组件只有一个父部件时,很难共享 最大化Component接口? 声明管理子部件的操作:在安全性和透明性之间权衡 Component是否应该实现一个Component列表? 子部件排序 使用高速缓存存储改善性能 应该由谁删除Component 存储组件最好用哪一种数据结构: List, Array, HashMap?,2019/5/5,Institute of Computer Software Nanjing Unive
24、rsity,37,Related Patterns,Decorator经常和Composite一起使用,通常有一个公共的父类 Flyweight可以共享组件但是不再能引用他们的父类对象 Iterator:可用来遍历Composite Visitor:将本来应该分布在Composite和Leaf类中的操作和行为局部化,2019/5/5,Institute of Computer Software Nanjing University,38,思考题:考虑如何实现安全方式的Composite,Decorator,Aliases: Wrapper Intent 动态地给一个对象添加一些额外的职责。就增
25、加功能来说,Decorator模式相比生成子类更为灵活 动机 希望给某个对象而不是整个类添加一些功能,2019/5/5,Institute of Computer Software Nanjing University,39,Example,2019/5/5,Institute of Computer Software Nanjing University,40,Example,2019/5/5,Institute of Computer Software Nanjing University,41,Applicability,在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责 处
26、理那些可以撤销的职责 当不能采用生成子类的方法进行扩充时 可能有大量独立的扩展,为支持每一种组合将产生大量的子类 类定义被隐藏或者类定义不能用于生成子类,2019/5/5,Institute of Computer Software Nanjing University,42,Structure,2019/5/5,Institute of Computer Software Nanjing University,43,Participants,Component 定义一个对象接口,可以给这些对象动态地添加职责 ConcreteComponent 定义一个对象,可以给这个对象添加一些职责 Dec
27、orator 维持一个指向Component对象的指针,并定义一个与Component接口一致的接口 ConcreteDecorator 向组件添加职责,2019/5/5,Institute of Computer Software Nanjing University,44,Collaboration,Decorator将请求转发给它的Component对象,并有可能在转发请求前后执行一些附加的动作。,2019/5/5,Institute of Computer Software Nanjing University,45,Sample Code,New Decorator1( new De
28、corator2 ( new Decorator3 ( new ConcreteComponent(),ConcreteComponent,Decorator1,Decorator2,Decorator3,思考题:查看Java IO包,思考其中所使用的设计模式,包裹图,Consequence,优点 比静态继承更灵活 避免在层次结构高层的类有太多的特征 缺点 Decorator与它的Component不一样,使用装饰时不应该依赖对象标识 有许多小对象,2019/5/5,Institute of Computer Software Nanjing University,46,Implementat
29、ion,接口的一致性,装饰对象的接口必须与它所装饰的Component的接口是一致的 当仅需要添加一个职责时可以省略抽象的Decorator类 保持Component类的简单性 改变对象外壳与改变对象内壳的区别,结合Strategy模式,2019/5/5,Institute of Computer Software Nanjing University,47,Related Patterns,Adapter:Decorator模式中装饰仅改变对象的职责而不改变它的接口,而Adapter模式中适配器将给对象一个全新的接口 Composite:可以将装饰视为一个退化的仅有一个组件的组合,Decor
30、ator的目的不在于对象聚集 Strategy:用一个装饰可以改变对象的外表,而Strategy模式可以改变对象的内核,2019/5/5,Institute of Computer Software Nanjing University,48,Facade,Intent 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使这一子系统更加容易使用 Motivation 使系统的各子系统之间的关联最小,引入一个facade对象,为子系统提供一个简单的、泛化的设施,2019/5/5,Institute of Computer Software Nanjing Uni
31、versity,49,Example,2019/5/5,Institute of Computer Software Nanjing University,50,Applicability,为一个复杂的子系统提供一个简单接口。 子系统往往会非常复杂,但是其接口应该尽可能地简单,特别是对于一般用户而言 客户与实现抽象功能的诸类之间存在一定的依赖性,facade可以降低这种依赖性 在多个子系统的结构中,使用facade模式定义子系统的入口点,有助于降低各子系统之间的依赖性,2019/5/5,Institute of Computer Software Nanjing University,51,S
32、tructure,2019/5/5,Institute of Computer Software Nanjing University,52,Participants,Facade 知道哪些子系统类负责处理请求 将客户的请求代理给适当的子系统对象 Subsystem classes 实现子系统的功能 处理由Facade对象指派的任务 没有facade的任何相关信息;即没有指向facade的指针,2019/5/5,Institute of Computer Software Nanjing University,53,Collaborations,客户程序通过发送请求给Facade的方式与子系统
33、通讯,Facade将这些消息转发给适当的子系统对象 使用Facade的客户程序不需要直接访问子系统对象,2019/5/5,Institute of Computer Software Nanjing University,54,Sample Code,Consequences,它对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便 它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。 化“紧耦合”为“松耦合” 实现组件软件的关键技术 并不限制应用使用子系统类,2019/5/5,Institute of Computer Software Na
34、njing University,55,Implementation,降低客户-子系统之间的耦合度,用抽象类实现Facade而它的具体子类对应于不同的子系统实现可以进一步解耦;另一种方法是用不同的子系统对象配置Facade对象 公共子系统类与私有子系统类,2019/5/5,Institute of Computer Software Nanjing University,56,Related Patterns,Abstract Factory模式可以与Facade模式一起使用以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象 Mediator模式与Facade模式的相似之处是,
35、它抽象了一些已有的类的功能 通常仅需要一个Facade对象,因此可以用Singleton模式,2019/5/5,Institute of Computer Software Nanjing University,57,Flyweight,Intent 运用共享技术有效支持大量细粒度的对象。 Motivation 当对象的粒度太小的时候,大量对象将会产生巨大的资源消耗,因此考虑用共享对象(flyweight)来实现逻辑上的大量对象。Flyweight对象可用于不同的context中,本身固有的状态(内部状态)不随context发生变化,而其他的状态(外部状态)随context而变化 Flywei
36、ght模式对那些通常因为数量太大而难以用对象来表示的概念或实体进行建模,2019/5/5,Institute of Computer Software Nanjing University,58,Example,2019/5/5,Institute of Computer Software Nanjing University,59,Example,2019/5/5,Institute of Computer Software Nanjing University,60,外部状态,作为参量传入,Flyweight对象,Applicability,一个应用程序使用了大量的对象 完全由于使用大量的
37、对象,造成很大的存储开销 对象的大多数状态都可变为外部状态 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象 应用程序不依赖于对象标识,2019/5/5,Institute of Computer Software Nanjing University,61,Structure,2019/5/5,Institute of Computer Software Nanjing University,62,Structure,Object graph,2019/5/5,Institute of Computer Software Nanjing University,63,Samp
38、le Code,Participants,Flyweight 描述一个接口,通过这个接口flyweight可以接受并作用于外部状态 ConcreteFlyweight 实现Flyweight接口,并为内部状态增加存储空间。必须是可以共享的,存储的状态必须是内部的。 UnsharedConcreteFlyweight 不强制共享 FlyweightFactory 创建并管理flyweight对象 确保合理地共享flyweight,提供已创建的flyweight实例或者创建一个(如果不存在的话) Client 维持一个对flyweight的引用 计算或存储一个(多个)flyweight的外部状态,
39、2019/5/5,Institute of Computer Software Nanjing University,64,Collaboration,Flyweight执行时所需的状态必定是内部或外部的。内部状态存储在ConcreteFlyweight中,外部对象则由Client对象存储或计算。当用户调用flyweight对象的操作时,将该状态传递给它 用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight对象,以保证对它们适当地进行共享,2019/5/5,Institute of Computer S
40、oftware Nanjing University,65,Consequences,把对象的状态分开:intrinsic and extrinsic 节约存储空间:内部状态的共享节约了大量空间,外部状态可通过计算获得从而进一步节约空间 Flyweight与Composite结合,形成一个共享叶节点的图。,2019/5/5,Institute of Computer Software Nanjing University,66,Implementation,删除外部状态:理想情况是,外部状态可以由一个单独的对象结构计算得到,且该结构的存储要求非常小 管理共享对象,客户不能直接实例化flywei
41、ght,必须通过管理器,例如FlyweightFactory。,2019/5/5,Institute of Computer Software Nanjing University,67,Related Patterns,与Composite模式结合起来,用共享叶节点的有向无环图实现一个逻辑上的层次结构 最好用Flyweight实现State和Strategy对象,2019/5/5,Institute of Computer Software Nanjing University,68,Proxy,Aliases:Surrogate Intent 为其它对象提供一种代理以控制对这个对象的访问
42、Motivation 对于每一个开销很大的对象,应该根据需要进行创建,2019/5/5,Institute of Computer Software Nanjing University,69,Example,2019/5/5,Institute of Computer Software Nanjing University,70,Applicability,在需要用比较通用和复杂的对象指针代替简单的指针时使用Proxy模式 Remote Proxy:为一个对象在不同的地址空间提供局部代表 Virtual Proxy:根据需要创建开销很大的对象 Protection Proxy:控制对原始对象
43、的访问,用于对象应该有不同访问权限的时候 Smart Reference:取代了简单的指针,在访问对象时执行一些附加操作引用计数,加锁,将第一次引用的持久对象装入内存,2019/5/5,Institute of Computer Software Nanjing University,71,Structure,2019/5/5,Institute of Computer Software Nanjing University,72,不改变主题接口,不让客户端感觉到代理的存在,将客户端的调用委派给真实的主题对象,传递请求之前/之后都可以执行特定的操作,而不是单纯传递请求,Participants
44、,Proxy 保存一个引用使得proxy可以访问实体 提供一个与Subject的接口相同的接口,这样proxy就可以用来代替实体 控制对实体的存取,并可能负责创建和删除它 Subject 定义RealSubject和Proxy的共同接口 RealSubject 定义Proxy所代表的实体,2019/5/5,Institute of Computer Software Nanjing University,73,Collaboration,Proxy根据其种类,在适当的时候向RealSubject转发请求,2019/5/5,Institute of Computer Software Nanji
45、ng University,74,Sample Code,Consequences,Proxy模式在访问对象时引入了一定程度的间接性 Remote proxy可以隐藏一个对象存在于不同地址空间的事实 Virtual proxy可以进行最优化 Protection Proxy和Smart Reference都允许在访问一个对象时有一些附加的内务处理 可以对用户隐藏一种copy-on-write的优化方式,该优化与根据需要创建对象有关,2019/5/5,Institute of Computer Software Nanjing University,75,Implementation,语言特性
46、C+:重载存取运算符 Smalltalk:使用doesNotUnderstand Proxy并不总需要知道实体的类型,2019/5/5,Institute of Computer Software Nanjing University,76,Related Patterns,Adapter模式中适配器为它所适配的对象提供了一个不同的接口,而Proxy则提供了与它的实体相同的接口,或其接口的子集(Protection Proxy可能会拒绝执行实体的操作) Decorator的实现和Proxy类似,但目的不同:Decorator对象添加一个或多个功能,而Proxy则控制对对象的访问,2019/5/
47、5,Institute of Computer Software Nanjing University,77,Summary:Structural Patterns,Adapter 、Bridge、Facade Adapter用于两个已有的不兼容接口之间的转接 Bridge用于将一个抽象与多个可能的实现进行桥接 Facade用于为复杂的子系统定义一个新的简单易用的接口 Composite、Decorator和Proxy Composite用于构造对象(递归)组合结构 Decorator用于为对象增加新的职责 Proxy为目标对象提供一个替代者 Flyweight 针对细粒度对象的一种全局控制手段,2019/5/5,Institute of Computer Software Nanjing University,78,作业,比较Adapter,Bridge和Facade的相似点与不同点 比较Composite,Decorator和Proxy的相似点与不同点 学习Java2.0对代理模式的支持介绍java.lang.reflect.Proxy, java.lang.reflect.InvocationHandler的使用,2019/5/5,Institute of Computer Software Nanjing University,79,
链接地址:https://www.31doc.com/p-2679653.html