1、 1、工厂方法模式、工厂方法模式主讲:田旭园程序:奚亮亮ppt :叶良波答问:陈才国1页页FACTORY METHOD请MM去麦当劳吃汉堡,不同的MM有不同的口味,要每个都记住是一件烦人的事情,我一般采用Factory Method模式,带着MM到服务员那儿,说要一个汉堡,具体要什么样的汉堡呢,让MM直接跟服务员说就行了。工厂方法模式:核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。感谢王良芳大神在校内的分享,新增20种模式的形象比喻。缺:简单工厂模式、缺省适配模式和不变模式
2、。创建模式:简单工厂、工厂方法、抽象工厂、单例、建造、模型;结构模式:适配器、缺省适配、合成、装饰、代理、享元、门面、桥梁;行为模式:不变、策略、模板方法、观察者、迭代子、责任链、命令 备忘录、状态、访问者、解释器、调停者。(最后三种不讲) 工厂方法模式是类的创建模式,又叫虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。 工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际工作推迟到子类中。工厂方法解决问题:工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了
3、它的缺点。工厂方法缩略图 该模式的优点: 这种抽象的结果,使这种工厂方法模式可以用来允许系统不修改具体工厂角色的情况下引进新产品,这一特点无疑使得工厂模式具有超过简单工厂模式的优越性。在工厂方法模式中,一般都有一个平行的等级结构,也就是说工厂和产品是对应的的。抽象工厂对应抽象产品,具体工厂对应具体产品。简单的示意图如下:各种角色分类 抽象工厂角色: 具体工厂角色: 抽象产品角色: 具体产品角色:72、简单工厂模式主讲人:陈儒组员:韩政高、戴鹏军、陈群1页页8简单的介绍简单工厂模式是创建型模式,用于对象的创建,它不属于23种gof设计模式。它是工厂模式家族中最简单实用的模式,可以理解为是不同工厂
4、模式的一个特殊实现。 设计模式描述了软件设计过程中某一类常见问题的一般性的解决方案,是解决某个方向上的变动需求的问题。而工厂设计模式的存在是为了解决哪一方面的问题呢?或者说它的动机是什么呢?9动机在软件系统中,经常面临着“某个对象”的创建工作;由于需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如何应对这种变化?如何提供一种“封装机制”来隔离出“这个易变对象”的变化,从而保持系统中“其他依赖该对象的对象”不随着需求改变而改变?10优缺点 优点:简单工厂模式主要用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系会导致软件的脆弱。通过使用工
5、厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的明确了各自的职责和权利,有利于整个软件体系结构的优化。 缺点:由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。 3、抽象工厂模式 by: 缪丹权 柳敏乾 李青振 2页页FACTORY追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说来四个鸡翅就行了。麦当劳和肯德
6、基就是生产鸡翅的Factory工厂模式:客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供。抽象工厂模式定义对象创建型模式,又称Kit模式。 在中对Abstract Factory的意图是这样描述的:为了创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。有时候,几个对象需要一种协调的方式实例化。例如,在处理用户界面时,系统可能在一个操作系统上用一组对象,在另一个系统上用另一组对象。Abstract Factory 确保系统根据情况获得正确的对象。产品族
7、产品族,是指位于不同产品等级结构中,功 能相关联的产品组成的家族。比如下图中,箭头所指就是三个功能相关联的产品。它们位于三个不同的等级结构中的相同位置上,组成了一个产品族。为什么需要AF 为什么需要AF 如果,现在有三个相似的工厂等级结构,那么采用工厂方法模式就势必要使用三个独立的工厂等级结构。由于三个等级结构相似性,会导致三个平行的等级结构。随着产品等级结构的数目增加,工厂方法模式所给出的工厂等级结构的数目也会增加。抽象工厂模式结构图结构与角色抽象工厂 (AbstractFactory)角色: 担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。通常使用JAVA接口或者抽象J
8、AVA类来实现,而所有的具体工厂类必须实现该接口或者继承抽象类。具体工厂类 (Conrete Factory)角色: 这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑。通常使用具体类来实现这个角色。抽象产品(Abstract Product)角色: 担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。通常使用接口或者抽象类来实现这一角色。具体产品(Concrete Product)角色: 抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。通常使用具体JAVA类来实现。抽象工厂模式时序图 在客户新建一个抽象工厂的时候,其实是新建了一个
9、具体的工厂,然后再通过该具体工厂来创建各种具体的产品。抽象工厂模式优缺点优点:s 程序设计中有三种耦合:零耦合、抽象耦合、具体耦合。抽象工厂设计可以很好的把具体耦合转换到抽象耦合来减少耦合程度。s 具体产品从客户代码中被分离出来。s 容易改变产品的系列。s 将一个系列的产品族统一到一起创建。抽象工厂模式优缺点缺点:u由于每个类的产生都要继承抽象类(或接口),并由工厂来创建,这样就增加了代码长度和工作量。u在产品族中扩展新的产品是很困难的,它需要修改抽象工厂的接口。u使软件结构更复杂。与其他模式的区别和联系与工厂模式的区别:工厂方法模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂方
10、法模式的推广。工厂方法模式用来创建一个产品的等级结构的,而抽象工厂模式是用来创建多个产品的等级结构的。工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。 总结 工厂的实现通常使用Singleton模式。一个应用中一般每个系列产品只需要使用一个具体工厂的实例。 抽象工厂模式提供了一个创建一系列相关或相互依赖的对象的接口,关键点在于应对”多系列对象创建”的需求变化。 学会抽象工厂模式,可以更好地理解面向对象中的原则: 面向接口编程,而不要面向实现编程。组员:汤仲喆组员:汤仲喆 王凯王凯 李义冬李义冬主讲:汤仲喆主讲:汤仲喆代码:王凯代码:王凯答辩:李义冬答辩:李义冬4、The Sin
11、gleton Pattern (单例模式)(单例模式)1页页SINGLETON俺有6个漂亮的老婆,她们的老公都是我,我就是我们家里的老公Sigleton,她们只要说道老公,都是指的同一个人,那就是我(刚才做了个梦啦,哪有这么好的事)单例模式:单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的单一实例的需求时才可使用。 什么是单例模式顾名思义,单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 单例模式的要点(1)某个类只能有一个实例;(2)它必须自行创建这个实例;(3
12、)它必须自行向整个系统提供这个实例。解决方案-单例模式意图:希望类只有一个实例,但没有控制类实例化的全局变量(对象)。同时希望确保所有客体对象使用该类的相同实例,而无需将引用传给它们。问题:几个不同的客户对象需要引用同一个对象,而且希望确保这种类型的对象数目不超过一个。解决方案:保证一个实例参与者与协作者:客户对象只能通过getInstance()方法创建单例类的实例。效果:客户对象无需操心是否存在单例类的实例,实例化有单例类自己控制。实现:一个引用单例对象的静态私有成员变量一个公共静态方法,负责实现一次性的实例化并返回对单例对象的引用设置为保护或私有的构造方法单例模式的关键特征单例模式设计会
13、产生什么问题? 在多线程程序中,Singleton模式可能会出现一个问题。假设对getInstance()方法的两个调用几乎同时发生,这种情况可能非常糟糕。此时会发生什么?1.第一个线程检查实例是否存在。因为实例不存在,该线程执行创建第一个实例的代码部分。2.然而,假设在实例化完成之前,另一个线程也来检查实例成员变量是否为null。因为第一个线程还什么都没有创建,实例成员变量仍然等于null,所以第二个线程也执行了创建一个对象的代码。3.现在,两个线程都执行了Singleton对象的new操作,因此创建了两个重复的对象。懒汉式 VS 饿汉式所以,到底使用哪一种方式,要看实际的需求。n饿汉式:静
14、态初始化方式,在启动加载单例类时就实例化对象,只实例化一次,以后用到的时候就不需要再去实例化了,加载类的时候速度比较慢,但以后获得对象时的速度比较快,该对象从加载到应用结束一直占用资源。n懒汉式:相当于一个延迟加载机制,即你需要这个对象时候才去实例化,加载类的时候速度比较快,但以后获得对象时的速度比较慢,该对象在整个应用的生命周期只有一部分时间占用资源。面临多线程访问的安全性问题,需要做双重锁定处理才可以保证安全。单例模式的应用 一个随机数产生的例子 在整个应用程序中只需要一个类的实例来产生随机数,客户端程序从类中获取这个实例,调用这个实例的方法nextInt(),公用的方法访问需要进行同步,
15、这是单例模式需要解决的同步问题。参与者:Singleton定义一个Instance操作,允许客户访问它的唯一实例,Instance是一个类操作,负责创建自己的唯一实例。协作关系:客户只能通过Singleton的Instance操作访问一个Singleton的实例。主讲:范允易小组成员:陈巧燕、刘秀颖、郭娟5、建造者模式(Builder Pattern) -创建型模式1页页BUILDERMM最爱听的就是我爱你这句话了,见到不同地方的MM,要能够用她们的方言跟她说这句话哦,我有一个多种语言翻译机,上面每种语言都有一个按键,见到MM我只要按对应的键,它就能够用相应的语言说出我爱你这句话了,国外的MM
16、也可以轻松搞掂,这就是我的我爱你builder。(这一定比美军在伊拉克用的翻译机好卖)建造模式:将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。概述概述Builder模式是一种创建型模式,它主要是应对项目中一些复杂对象的创建工作。所谓“复杂对象”是指:此对象中还含有其它的子对象。意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。-设计模式GOF Builder模式结构l 建造者(Builder)角色l 具体
17、建造者(Concrete Builder)角色l 产品(Product)角色l 指导者(Director)角色时序图时序图优缺点和适用性优缺点和适用性1.解耦了组装过程和创建具体部件2.职责分离3.精细的控制创建过程4.难于应付“分步骤构建算法”的需求变动适用性:1.复杂的内部结构2.相互依赖的各部分3.创建过程独立4.各部分变化剧烈,组合算法相对稳定相关模式相关模式抽象工厂(Abstract Factory)模式共性:创建型模式、创建类对象区别:Abstract Factory模式:解决“系列对象”的需求变化Builder模式:解决“对象部分”的需求变化总结总结Builder模式的实质是:解
18、决一个复杂对象的创建工作。明确变化的部分和相对稳定的部分,隔离变化,解耦稳定的组装过程和变化的具体部件,使得我们不用去关心每个部件是如何组装的;如何将具体部件和组装算法隔离是要解决的问题。什么是原始模型模式?什么是原始模型模式?属于对象的创建模式。通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。 结构:结构:第一种是简单形式第一种是简单形式第二种是登记形式第二种是登记形式6、原始模型模式小组分工:做报告:郑迟回答问题:徐冰,俞栋辉代码:王炜2页页PROTOTYPE跟MM用QQ聊天,一定要说些深情的话语了,我搜集了好多肉麻的情话,需要时只要co
19、py出来放到QQ里面就行了,这就是我的情话prototype了。(100块钱一份,你要不要)原始模型模式:通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象。原始模型模式允许动态的增加或减少产品类,产品类不需要非得有任何事先确定的等级结构,原始模型模式适用于任何的等级结构。缺点是每一个类都必须配备一个克隆方法。简单形式 这种形式涉及到三个角色:这种形式涉及到三个角色:客户(Client)角色:客户类提出创建对象的请求。抽象原始(Prototype)角色:这是一个抽象角色,通常由一个java接口或java抽象类实现。此角色给出所有的具体原始类所需要
20、的接口。具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。 简单形式 UML图登记形式这种形式涉及到三个角色:这种形式涉及到三个角色:客户端(Client)角色:客户端类向管理员提出创建对象的请求。 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个接口或抽象类实现。 此角色给出所有的具体原型类所需要的接口。 具体原型(Concrete Prototype)角色:被复制的对象。需要实现抽象原型角色所要求的接口。 原型管理器(Prototype Manager)角色:创建具体原型类的对象,并记录每一个被创建的对象。 登记形
21、式 UML图两种形式的比较 简单形式和登记形式的原始模型模式各有其长处和短处。 1)如果需要创建的原型对象数目较少而且比较固定的话,可以采取第一种形式,也即简单形式的原始模型模式。在这种情况下,原型对象的引用可以由客户端自己保存。 2)如果要创建的原型对象数目不固定的话,可以采取第二种形式,也即登记形式的原始模型模式。在这种情况下,客户端并不保存对原型对象的引用,这个任务被交给管理员对象。在复制一个原型对象之前,客户端可以查看管理员对象是否已经有一个满足要求的原型对象。如果有,可以直接从管理员类取得这个对象引用;如果没有,客户端就需要自行复制此原型对象。 模式的实现1):浅复制(浅克隆) 被复
22、制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象,换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 2):深复制(深克隆) 被复制对象的所有的变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍,而这种对被引用到的对象的复制叫做间接复制。 模式的实现 利用串行化来作深复制 把对象写到流里的过程是串行化(Serilization)过程,非常形象的称为“冷冻”或是“腌咸菜”过程。而把对象从流中读出来的并行化(D
23、eserialization)过程叫做“解冻”或是“回鲜”过程。写到流里的是对象的一个拷贝,而原来对象仍然存在于JVM里面,因此“腌成咸菜”(串行化)的只是对象的一个拷贝。java咸菜(并行化)还可以回鲜。 模式的实现 串行化的结构图浅复制 UML图深复制 UML图原始模型模式的优缺点特有的优点 (1):原始模型模式原许动态地增加或减少产品类。由于创建产品类实例的方法是产品类内部具有的,因此,增加新产品对整个结构没有影响。 (2):原始模型模式提供简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而原始模型模式就不需要这样。 (3):具有给一个应用软件动态加载新功能的能
24、力。例如,一个分析Web服务器的记录文件的应用软件,针对每一种记录文件格式,都可以由一个相应的“格式类”负责。如果出现了应用软件所不支持的新的Web服务器,只需要提供一个格式类的克隆,并在客户端登记即可,而不必给每个软件的用户提供一个全新的软件包。 (4):产品类不需要非得有任何事先确定的等级结构,因为原始模型模式适合用于任何的等级结构。主要缺点:每一个类都必须配备一个克隆方法,配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类来说不是很难,而对于已经有的类不一定很容易,特别是当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 7、The Adaptor Pattern(适配
25、器模式)主讲:顾祝燕组员:耿惠、何振芬、朱金凤2页页ADAPTER在朋友聚会上碰到了一个美女Sarah,从香港来的,可我不会说粤语,她不会说普通话,只好求助于我的朋友kent了,他作为我和Sarah之间的Adapter,让我和Sarah可以相互交谈了(也不知道他会不会耍我)适配器(变压器)模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。适配类可以根据参数返还一个合适的实例给客户端。面向对象软件系统的适配问题 假设我们已经有一个软件系统,原来使用了一个第三方类库A。现在有一个新的第三方类库B,其功能等各方面都更加强大。我们希望用B
26、来替换A,以改善我们的系统。但是B的接口与A不一样。那怎么办呢?Adapter模式 定义 将一个类的接口转换成客户端所期望的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 别名 包装器WrapperAdapter模式动机 有时,为复用而设计的工具箱类不能够被复用的原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配(名称不一样,参数不一样,等等)。我们可以改变工具箱类使它兼容专业领域中的类的接口,但前提是必须有这个工具箱的源代码。然而即使我们得到了这些源代码,修改工具箱也是没有什么意义的;因为不应该仅仅为了实现一个应用,工具箱就不得不采用一些与特定领域相关的接口。
27、动机(续) 我们可以不用上面的方法,而定义一个适配器类,由它来适配工具箱的接口和专业应用的接口。我们可以用两种方法做这件事: 1) 继承专业应用类的接口和工具箱类的实现。这种方法对应A d a p t e r模式的类版本(多继承) 2) 将工具箱类的实例作为适配器类的组成部分,并且使用工具箱的接口实现适配器类。这种方法对应A d a p t e r模式的对象版本。Adapter模式 适用性 以下情况使用A d a p t e r模式 你想使用一个已经存在的类,而它的接口不符合你的需求。 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。A
28、dapter模式 结构(类版本)Adapter模式 结构(对象版本)基于类的Adapter模式 基于类的Adapter模式的一般结构如下:Adaptee类为Adapter的父类,Adaptee类为适配源,适配目标(接口)也是Adapter的父类;基于类的Adapter模式比较适合应用于Adapter想修改Adaptee的部分方法的情况。 基于对象的Adapter模式 基于对象的Adapter模式的一般结构如下:Adaptee类对象为Adapter所依赖,适配目标(接口)是Adapter的父类; 基于对象的Adapter模式比较适合应用于Adapter想为Adaptee添加新的方法的情况。但在A
29、daptee类的方法与Adapter类的方法不同名而实现相同功能的情况下,我们一般也使用基于对象的Adapter模式, Adapter模式 参与者 Ta r g e t C l i e n t使用的与特定领域相关的“接口”。 C l i e n t 与符合Ta rg e t接口的对象协同的专业系统。 A d a p t e e 一个已经存在的“接口”,它具有Client要求的功能但不符合Client的接口要求。这个接口需要适配。 A d a p t e r 对A d a p t e e的接口与Ta rg e t接口进行适配Adapter模式协作 Client在A d a p t e r实例上调
30、用一些操作(请求)。接着适配器调用A d a p t e e的操作实现这个请求。效果(类适配器和对象适配器有不同的权衡) 类适配器 用一个具体的A d a p t e r类对A d a p t e e和Ta rg 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。Adapter模式 效果(类适配器和对象适配器有不同
31、的权衡) 对象适配器则 允许一个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本身。8、缺省适配模式(Default Adapter) -杨鹏、余晖、许超杰1页页问题的提出:鲁智深的故事这个抽象的天星类便是一个适配器类,鲁智深实际借助于适配器类模式达到
32、了剃度的目的。此适配器类实现了和尚接口所要求的所有方法。但是与通常的适配器模式不同的是,此适配器类给出所有的方法的实现都是“平庸”的。这种“平庸化”的适配器模式称作缺省适配模式缺省适配模式缺省适配模式(Default Adapter) 一、概述 缺省适配模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。当不需要全部实现适配器接口提供的方法时,可先设计一个抽象类实现适配器接口,并为接口中每个方法提供一个默认实现(空方法)。那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。二、结构二、结构缺省适配模式(Default Adapter)Public
33、interface AbstractService void serviceOperation1(); int serviceOperation2(); String serviceOperation3();Public class ServiceAdapter implements AbstractService public void serviceOperation1() public int serviceOperation2()return 0; public String serviceOperation3()return null; 缺省适配模式小结 在任何时候,如果不准备实现一
34、个接口的所有方法时,就可以模仿WindowApdapter的做法制造一个抽象类,给出所有方法的平庸的实现。这样从这个抽象类继承下去的子类就不必实现所有的方法了。 适配器模式把一个类的接口换成客户端所期待的另一个接口。缺省适配模式-适配器模式的“平庸化”形式可以使所考察的类不必实现不需要的那部分接口。9、composite(合成合成)模式模式讲解人:陈敖其他成员:黄文,林丽丽,林温柔2页页COMPOSITEMary今天过生日。我过生日,你要送我一件礼物。嗯,好吧,去商店,你自己挑。这件T恤挺漂亮,买,这条裙子好看,买,这个包也不错,买。喂,买了三件了呀,我只答应送一件礼物的哦。什么呀,T恤加裙子
35、加包包,正好配成一套呀,小姐,麻烦你包起来。.,MM都会用Composite模式了,你会了没有?合成模式:合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式就是一个处理对象的树结构的模式。合成模式把部分与整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和由他们复合而成的合成对象同等看待。Composite模式 别名:部分-整体模式;组合模式;合成模式 要点:如何设计单个对象和组合对象,使他们具有一致的操作接口。 Composite模式把部分和整体关系用树结构表示,是属于对象的结构模式。 Composite模式要对Composite的对象进行管理,所以在一定
36、位置给予对象的相关管理方法,如:add(),remove()等. Composite模式中对象的管理有两种方案。 安全方式:此方式只允许树枝构件有对象的管理方法。 透明方式:此方式只允许树枝和树叶都有对象的管理方法,但树叶对象中的管理方法无实际意义。组成部分: component构件:抽象组合对象的公共行为接口 leaf构件:树叶对象,没有下级子对象 composite构件:树枝对象,树枝对象可以包含一个或多个其他树枝或树叶对象UML示意图:安全方式:透明方式:安全式特点:错误地调用会导致编译时出错透明式特点:编译时不会出错,错误地调用会导致抛出异常 优点: 可以清楚地定义分层次的复杂对象,表
37、示对象的全部或部分层次,使得增加新构件也更容易。 客户端调用简单,客户端可以一致的使用组合结构或其中单个对象。 定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,这样不断递归下去,可以形成复杂的树形结构。 很容易在组合体内加入对象构件,客户端不必因为加入了新的对象构件而更改原有代码。 缺点: 设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联。 增加新构件时可能会产生一些问题,很难对容器中的构件类型进行限制。适用环境: 需要表示一个对象整体或部分层次,在具有整体和部分的层
38、次结构中,希望通过一种方式忽略整体与部分的差异,可以一致地对待它们。 让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无需关心对象层次结构的细节。 对象的结构是动态的并且复杂程度不一样,但客户需要一致地处理它们。10、装饰模式、装饰模式Presented by 马庆 沈月云 彭怡然 姚敏2页页DECORATORMary过完轮到Sarly过生日,还是不要叫她自己挑了,不然这个月伙食费肯定玩完,拿出我去年在华山顶上照的照片,在背面写上最好的的礼物,就是爱你的Fita,再到街上礼品店买了个像框(卖礼品的MM也很漂亮哦),再找隔壁搞美术设计的Mike设计了一个漂亮的盒子装起来.,我们都是
39、Decorator,最终都在修饰我这个人呀,怎么样,看懂了吗?装饰模式:装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。动态给一个对象增加功能,这些功能可以再动态的撤消。增加由一些基本功能的排列组合而产生的非常大量的功能。Company Logo1.装饰模式介绍意图意图 动态地给一个对动态地给一个对象添加一些额外象添加一些额外的职责。就增加的职责。就增加功能来说,功能来说,Decorator模式比模式比生成子类更为灵生成子类更为灵活活Decorator模式模式工作原理工作原理 可以创建始于可以创建始于Decorator对象(负对象(负责新功能的对象
40、)责新功能的对象)终于原对象的一个终于原对象的一个对象对象“链链”Company Logo1.装饰模式介绍 装饰模式的定义装饰模式可以动态的给一个对象附加一些功能。使用装饰模式扩展功能不会产生类爆炸。它采用的是合成方式,比继承方式更加灵活。 装饰模式要解决的问题提供一种修改类的行为,而避免创建众多的派生类的途径。 Company Logo3.讨论v面向对象设计的开面向对象设计的开-闭原则闭原则v类应该对扩展开放,对修改封闭。类应该对扩展开放,对修改封闭。 目的是在不需修改已有代码的情况下方便的扩展类的功能。按照这一原则设计的系统具有以下优点: 具有一定的适应性和灵活性。 具有一定的稳定性和延续
41、性。v“对扩展开放,对修改封闭。对扩展开放,对修改封闭。”这听起来自这听起来自相矛盾啊!有哪些方法可以不修改已有代码相矛盾啊!有哪些方法可以不修改已有代码但又能扩展其功能?但又能扩展其功能?v何时使用开闭原则?何时使用开闭原则?Company Logo3.讨论v何谓装饰?如何装饰?何谓装饰?如何装饰? 所谓装饰就是将一个对象包装起来。所谓装饰就是将一个对象包装起来。在程序上也就是让一个对象在程序上也就是让一个对象a包含另一个对包含另一个对象象b。a对应的类对应的类A是是“装饰类装饰类”,b对应的类对应的类B是是被装饰类。被装饰类。如果要让装饰可以重复,且不必考虑次序,如果要让装饰可以重复,且不
42、必考虑次序,那么装饰的要点是装饰者和被装饰者具有那么装饰的要点是装饰者和被装饰者具有相相同的类型同的类型(有共同的父类)。(有共同的父类)。Company Logo3.讨论首先生成一个首先生成一个DarkRoast对象对象DarkRoastCost()DarkRoast继承了Beverage,拥有一个计算饮料价格的方法cost()。Company Logo3.讨论MochaCost()然后然后DarkRoastCost()Mocha对象是装饰者,他与被它装饰的对象DarkRoast具有相同的类型(是Beverage的子类),也有一个cost()方法。顾客想要mocha,所以我们创建一个Moch
43、a对象,并用它包装DarkRoast.Company Logo3.讨论再然后再然后MochaCost()DarkRoastCost()whip对象是装饰者,他与被它装饰的对象DarkRoast具有相同的类型,也有一个cost()方法。顾客还想要whip,所以我们创建一个Whip对象,并用它包装Mocha.WhipCost()Company Logo3.讨论计算饮料的价格计算饮料的价格MochaCost()DarkRoastCost()调用最外层的装饰者whip的cost(),whip再将计算任务委派给被它包装的对象,得到一个价格后,再加上whip自己的价格.WhipCost()5.005.00
44、+0.505.50+1.006.50Company LogoDiagram所谓委派就是一个对象将工作(或工作的所谓委派就是一个对象将工作(或工作的一步分)交给另一个对象来完成。一步分)交给另一个对象来完成。在装饰模式中,委派是指在装饰模式中,委派是指装饰对象装饰对象将任务将任务交给交给被装饰对象被装饰对象来完成。来完成。委派可以传递,最终必须要有一个委派可以传递,最终必须要有一个干实事干实事的对象的对象。v何谓委派?何谓委派?Company Logo3.讨论装饰者在委派它装饰的装饰者在委派它装饰的对象作某种处理时,可对象作某种处理时,可以添加上自己的行为以添加上自己的行为(功能扩展)(在委派(
45、功能扩展)(在委派之前或之前或/和之后)。和之后)。装饰者与被装饰者装饰者与被装饰者具有相同的类型具有相同的类型对象可以在任何时候被对象可以在任何时候被装饰,因此我们能在运装饰,因此我们能在运行时动态的装饰对象。行时动态的装饰对象。可以用多个装饰可以用多个装饰者装饰一个对象者装饰一个对象由于装饰者与被装饰者由于装饰者与被装饰者具有相同的类型,我们具有相同的类型,我们可以用装饰后的对象代可以用装饰后的对象代替原来的对象。替原来的对象。要点要点Company Logo HouseBlendCost()BeveragedescriptiongetDescription()Cost()/Other m
46、ethodsDarkRoastCost()DecafCost()EspressoCost()CondimentDecoratorgetDescription()MochaBeverage beveragegetDescription()Cost()WhipBeverage beveragegetDescription()Cost()具体的咖啡品种调味品装饰者,不仅实现cost(),还要实现getDescription()考虑一下本讲开头的引例是如何实现的。咖啡店的类图咖啡店的类图Proxy pattern 11、 代理模式小组成员:王建奇,王洪军,嵇海锋,吴水生2页页PROXY跟MM在网上聊天
47、,一开头总是hi,你好,你从哪儿来呀?你多大了?身高多少呀?这些话,真烦人,写个程序做为我的Proxy吧,凡是接收到这些话都设置好了自动的回答,接收到其他的话时再通知我回答,怎么样,酷吧。代理模式:代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用。代理就是一个人或一个机构代表另一个人或者一个机构采取行动。某些情况下,客户不想或者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客户端分辨不出代理主题对象与真实主题对象。代理模式可以并不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,这时候代理对象不能够创建被代理对象,被代理对象必须有系统的其他角色
48、代为创建并传入。代理模式的定义定义 代理模式(Proxy Pattern), 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下 ,一个客户不 想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 代理,指的就是一个角色代表另一个角色采取行动,就象在实验室,用代理上网,我们设置一个代理地址把任何http请求转发到代理软件ccporxy或者squid,代理软件再去请求实际的web服务器,而它把获得的结果返回给用户,结束一次访问。代理模式的基本UML类图Subject obj = new Proxy ()代理模式的基本时序图 代理模式一般涉及到的角色 抽象主题
49、(Subject) 它是一个对象和它的代理所公用的接口,即realsubject 和proxy实例所实现的接口,这样就在任何使用realsubject的地方都可以使用Proxy。 实际主题(RealSubject) 实现抽象主题接口的类。 代理(Proxy) 实现抽象主题接口的类,代理含有主题接口声明的变量,用来存放realsubject角色的实例引用,这样就可以控制对它所代理对象的访问。代理模式的应用 一般来说分为几种:远程(Remote)代理:也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。虚拟(Virtual)代理:根据需要将一个资源消耗很大或
50、者比较复杂的对象延迟的真正需要时才创建。 比如说你打开一个很大的HTML网页时,里面可能有很多的文字和图片,但你还是可以很快的打开它,此时你所看到的是所有的文字,但图片却是一张张的下载后才能看到。那些未打开的图片框,就是通过虚拟代理来代替了真实的图片,此时代理存储了真实图片的路径和尺寸。保护(Protect or Access)代理:控制对一个对象的访问权限。一般用于对象有 不同权限的时候。智能引用(Smart Reference)代理:当调用真实对象时,代理出来另外一些事,提供比对目标对象额外的服务。 如:计算真实对象的引用次数,这样当该对象没有引用时,可以自动释放它;或当第一次引用一个持久