




已阅读5页,还剩223页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
哈尔滨工业大学计算机学院唐好选Email:tanghx,软件设计模式,主要内容,软件设计模式基础创建型模式结构型模式行为型模式,软件设计模式基础,广义讲,软件设计模式是可解决某类软件问题并能重复使用的软件设计方案狭义讲,软件设计模式是“对特定场景下解决一般设计问题的类和相互通信对象的描述”。是在类和对象的层次描述的可重复使用的软件设计问题的解决方案模式体现程序整体构思,也会出现在分析或概要设计阶段模式的核心思想:通过增加抽象层,把变化部分从那些不变部分里分离出来,设计模式的概念,(1)模式名称(PatternName)(2)问题(Problem):描述应在何时使用模式。解释了设计问题和问题存在的前因后果,可能还描述模式必须满足的先决条件(3)解决方案(Solution):描述设计的组成成分、相互关系及各自的职责和协作方式。模式就像一个模板,可用于多种场合,所以解决方案并不描述一个具体的设计或实现,而是提供设计问题的抽象描述和解决问题所采用的元素组合(类和对象)(4)效果(consequences):描述模式的应用效果及使用模式应权衡的问题,模式的基本要素,模式名和分类意图:设计模式是做什么的?它的基本原理和意图是什么?它解决的是什么样的特定设计问题?动机:说明一个设计问题以及如何用模式中的类、对象来解决该问题的特定情景适用性:什么情况下可以使用该设计模式?该模式可用来改进哪些不良设计?如何识别这些情况?结构:采用对象建模技术对模式中的类进行描述,如何描述设计模式,参与者:指设计模式中的类和/或对象以及它们各自的职责协作:模式的参与者如何协作并实现其职责效果:模式如何支持其目标?使用模式的效果和所需做的权衡取舍?系统结构的哪些方面可以独立改变?实现:实现模式时需了解的一些技术要点及应避免的缺陷,以及是否存在某些特定于实现语言的问题代码示例:说明怎样实现该模式的代码片段相关模式:与这个模式紧密相关的模式有哪些?其不同之处是什么?这个模式应与哪些其他模式一起使用?,描述设计模式(续),设计模式的原则,开-闭原则(OpenClosedPrincipal)单一职责原则(SingleResponsibilityPrinciple)里氏替换原则(LiskovSubstitutionPrinciple)依赖倒置原则(DependenceInversionPrinciple)接口隔离原则(InterfaceSegregationPrinciple)迪米特法则(最少知道原则)(LeastKnowledgePrinciple),设计模式就是实现了上述原则,从而达到代码复用、增加可维护性的目的,定义:对扩展是开放的,对修改是关闭的。开发软件时,可对其功能进行扩展(开放),进行扩展时,不需要对原程序进行修改(关闭)优点软件可用性较灵活,可对完成后的软件进行扩展,加入新功能,可通过不断增加新模块满足不断变化的新需求由于不修改软件原有的模块,不用担心软件的稳定性,开闭原则(OCP),就一个类而言,应该仅有一个引起它变化的原因。每一个引起类变化的原因就是一个职责,当类具有多职责时,应把多余职责分离出去,分别创建一些类来完成每一个职责每一个职责都是一个变化的轴线,当需求变化时会反映为类的职责的变化举例:interfaceModempublicvoiddial(Stringpno);publicvoidhangup();publicsend(charc);publiccharrecv();Modem类有两个职责:连接管理和数据通信,应将它们分离,单一职责原则(SRP),interfaceModemConpublicvoiddial(Stringpno);publicvoidhangup();interfaceModemCompublicsend(charc);publiccharrecv();,里氏替换原则(LSP),里氏替换原则是继承复用的基石,只有当派生类可以替换掉其基类,而软件功能不受影响时,基类才能真正被复用,派生类也才能够在基类的基础上增加新的行为LSP本质:在同一个继承体系中的对象应该有共同的行为特征例子:企鹅是鸟吗?生物学:企鹅属于鸟类LSP原则:企鹅不属于鸟类,因为企鹅不会“飞”违反LSP的后果:有可能需要修改客户代码,依赖倒置原则(DIP),高层模块不应依赖于低层模块,二者都依赖于抽象;抽象不应该依赖细节;细节应该依赖抽象高层模块只应该包含重要的业务模型和策略选择,低层模块则是不同业务和策略的实现高层抽象不依赖高层和低层模块的具体实现,最多只依赖于低层的抽象低层抽象和实现也只依赖于高层抽象辅助原则任何变量都不应该持有一个指向具体类的引用任何类都不应该从具体类派生任何方法都不应覆盖其任何基类中已经实现了的方法,接口隔离原则(ISP),使用多个专门的接口比使用单一的总接口要好一个类对另一个类的依赖性应当建立在最小的接口上一个接口代表一个角色,不应当将不同的角色都交给一个接口,没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染“不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。”换句话说,不要强迫客户使用它们不用的方法,如果强迫用户使用它们不用的方法,那么这些客户就会面临由于这些不使用方法的改变所带来的改变,最少知道原则(LKP),一个软件实体应当尽可能少地与其他实体发生相互作用每一个软件单位对其他单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系,在设计模式经典著作GOF95中,设计模式从应用的角度被分为三大类型创建型模式/结构型模式/行为型模式根据模式应用范围分,模式可应用于类,也可应用于对象类模式:处理类和子类之间的关系,这些关系通过继承建立,是静态的,在编译时刻便确定下来了对象模式:处理对象间的关系,这些关系在运行时刻是可以变化的,更具动态性从某种意义上来说,几乎所有模式都使用继承机制,所以“类模式”只指那些集中于处理类间关系的模式,而大部分模式都属于对象模式的范畴,设计模式的类型,创建型设计模式是用来创建对象的模式,该类模式抽象了实例化过程工厂模式:父类负责定义创建对象的公共接口,而子类则负责生成具体对象,将类的实例化操作延迟到子类中完成抽象工厂模式:为一个产品族提供统一的创建接口。当需要这个产品族的某一系列的时候,可以从抽象工厂中选出相应的系列创建一个具体的工厂类单件(Singleton)模式:保证一个类有且仅有一个实例,提供一个全局访问点,创建型设计模式,创建型设计模式,生成器(Builder)模式:将复杂对象创建与表示分离,同样的创建过程可创建不同的表示。允许用户通过指定复杂对象类型和内容来创建对象,用户不需要知道对象内部的具体构建细节原型(Prototype)模式:通过“复制”一个已经存在的实例来返回新的实例(不新建实例)。被复制的实例就是“原型”,这个原型是可定制的。原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效,结构型模式讨论的是类和对象的结构,它采用继承机制来组合接口或实现(类结构型模式),或者通过组合一些对象来实现新的功能(对象结构型模式)组合(Composite)模式:定义一个接口,使之用于单一对象,也可以应用于多个单一对象组成的对象组装饰(Decorator)模式:给对象动态添加额外的职责,就好像给一个物体加上装饰物,完善其功能代理(Proxy)模式:有些对象由于跨越网络或其他障碍,而不能或者不想直接访问另一个对象,直接访问会给系统带来不必要的复杂性,这时候可以在客户程序和目标对象之间增加一个中间代理对象,让代理对象来代替目标对象,结构型设计模式,结构型设计模式,享元(Flyweight)模式:享元是一个共享对象,它可以同时在不同上下文(Context)使用外观(Facade)模式:外观模式为子系统提供了一个更高层次、更简单的接口,从而降低了子系统的复杂度,使子系统更易于使用和管理。外观承担了子系统中类交互的责任桥梁(Bridge)模式:桥梁模式的用意是将问题的抽象和实现分离开来实现,通过用聚合代替继承来解决子类爆炸性增长的问题适配器(Adapter)模式:将一个类的接口适配成用户期待接口。一个适配器允许因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包装在一个已存在的类中,着力解决的是类实体之间的通讯关系,希望以面向对象的方式描述一个控制流程模版(Template)模式:定义了一个算法步骤,并允许子类为一个或多个步骤提供实现。子类在不改变算法架构的情况下,可重新定义算法中某些步骤观察者(Observer)模式:定义了对象之间一对多的依赖,当这个对象的状态发生改变的时候,多个对象会接受到通知,有机会做出反馈迭代子(Iterator)模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示,行为型设计模式,责任链(ChainofResponsibility)模式:多个对象由每一个对象对其下一个对象的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使系统可以在不影响客户端的情况下动态的重新组织链和分配责任备忘录(Memento)模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态命令(Command)模式:将请求及其参数封装成一个对象,作为命令发起者和接收者的中介,可以对这些请求排队或记录请求日志,以及支持可撤销操作,行为型设计模式,状态(State)模式:允许一个“对象”在其内部状态改变的时候改变其行为,不同状态表现不同行为访问者(Visitor)模式:表示作用于某对象结构中的各元素的操作。可在不改变元素类的前提下定义作用于这些元素的新操作解释器(Interpreter)模式:给定一个语言,定义其文法的表示,并定义一个解释器,该解释器使用文法表示来解释语言中的句子中介者(Mediator)模式:用一个中介对象来封装一系列的对象交互策略(Strategy)模式:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。策略模式使这些算法在客户端调用它们的时候能够互不影响地变化,行为型设计模式,创建型设计模式,工厂模式抽象工厂模式建造者模式单件模式原型模式,创建型设计模式,在面向对象编程中,使用new操作符构造对象实例是一种常规方法,但该方法存在一些约束条件和缺陷:(1)创建对象前须明确对象的类信息,但某些情况可能无法达到此要求,譬如打开一个视频文件需要一个播放器对象,但用户可能并不知道具体播放器,需要系统分派一个合适的播放器(2)复杂对象的创建需要多个步骤需计算或取得对象的初始设置需选择生成哪个子对象实例在生成所需对象之前必须先生成一些辅助对象新对象的创建是一个“过程”,而不是一个简单操作。为了能方便完成这些复杂对象的创建工作,可引入工厂模式,工厂模式的由来,工厂模式的结构,Product:定义工厂方法所创建对象的接口ConcreteProduct:实现Product接口Factory:声明工厂方法,返回一个Product对象。Factory也可定义工厂方法的缺省实现,返回一个缺省ConcreteProduct对象ConcreteFactory:重定义工厂方法,返回一个ConcreteProduct对象,工厂模式的参与者,日志管理器,支持两种类型日志FileLogEventLog,工厂模式实例,/LogFactory类publicabstractclassLogFactorypublicabstractLogCreate();,工厂模式实例分析,/FileFactory类publicclassFileFactory:LogFactorypublicoverrideFileLogCreate()returnnewFileLog();,/EventFactory类publicclassEventFactory:LogFactorypublicoverrideEventLogCreate()returnnewEventLog();,publicclassApppublicstaticvoidMain(stringargs)LogFactoryfactory1=newEventFactory();FileFactoryfactory2=newFileFactory();Loglog1=factory1.Create();Loglog2=factory2.Create();log1.Write();log2.Write();,工厂模式客户端程序,有效避免了具体产品对象和应用程序之间的耦合,增加了具体工厂对象和应用程序之间的耦合在类内部创建对象通常比直接创建对象更灵活工厂模式通过面向对象的手法,将具体对象的创建工作延迟到子类,提供了一种扩展策略,较好的解决了紧耦合问题,工厂模式实例分析,抽象工厂模式的由来,在软件系统中,经常面临“一系列相互依赖对象”的创建工作,由于需求变化,“一系列相互依赖的对象”也要改变,如何应对这种变化呢?如何像工厂模式一样绕过常规的”new”,提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?一种说法:可以通过工厂模式创建每个对象,但无法保证“相互依赖对象”之间的联系实例:Windows桌面主题,当更换一个桌面主题的时候,系统的开始按钮、任务栏、菜单栏、工具栏等都变了,而且是一起变的,色调都保持一致,类似这样的问题如何解决呢?应用抽象工厂模式,是一种有效的解决途径,抽象工厂模式的意图,意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类适用场合一个系统由多个产品系列中的一个来配置时强调一系列相关产品对象的设计以便进行联合时提供一个产品类库,只想显示其接口而非实现时需要创建的对象是一系列相互关联或相互依赖的产品族时,抽象工厂模式的结构,AbstractFactory:声明创建抽象产品对象的操作接口ConcreteFactory:实现创建具体对象的操作AbstractProduct:为一类产品对象声明一个接口ConcreteProduct:定义一个被具体工厂创建的产品对象,抽象工厂模式的参与者,实例:需要设计一个花园布局花园有三种风格:典雅型、实用型和懒人型花园中有3个位置需要种植植物:花台、墙角和花园中心,抽象工厂模式的应用实例,建造者(Builder)模式的由来,在软件系统中,有时面临“复杂对象”的创建工作,该复杂对象通常由各个部分的子对象用一定的算法构成这个复杂对象的各个部分经常面临剧烈变化,但是将它们组合在一起的算法却相对稳定如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?,建造者模式的意图和适用性,意图:将一个复杂的构建与表示相分离,使得同样的构建过程可以创建不同的表示适用性场合需要生成的产品对象有复杂的内部结构创建复杂对象的算法稳定,或可强迫生成一定顺序当构造过程允许被构造的对象有不同的表示时,建造者模式的结构,建造者模式的参与者,Builder:为创建一个Product对象的各个部件指定抽象接口ConcreteBuilder:实现Builder接口来构造和装配产品各个部件,提供一个检索产品的接口Director:构造一个使用Builder接口的对象Product:表示被构造的复杂对象,实例:设计游戏场景中的房屋房屋由五个部分组成:地板、墙壁、窗户、门和天花板构建房屋的步骤固定,而具体组件(门、窗等)易变采用建造者模式分离易变组件和稳定的构建过程,建造者模式的应用示例,publicabstractclassHouse/定义一个房屋抽象类publicabstractclassBuilder/这部分是易变的publicabstractvoidBuildFloor();/地板publicabstractvoidBuildDoor();/门publicabstractvoidBuildWindows();/窗户publicabstractvoidBuildWall();/墙壁publicabstractvoidBuildHouseCeiling()/天花板publicabstractHouseGetHouse();,建造者模式的应用示例,建造者模式的应用示例,publicabstractclassGameManager/规定构建次序publicstaticHouseCreateHouse(Builderbuilder)builder.BuildFloor();builder.BuildDoor();builder.Buildwall();builder.BuildWindows();builder.BuildHouseCeiling();returnbuilder.GetHouse();,建造者模式的应用示例,publicclassRomanHouseBuilder:BuilderpublicoverridevoidBuildDoor()publicoverridevoidBuildFloor()publicoverridevoidBuildWindows()publicoverridevoidBuildWall()publicoverridevoidBuildHouseCeiling()publicoverrideHouseGetHouse(),建造者模式的应用示例,classApppublicstaticvoidmain()Househouse=GameManager.CreateHouse(newRomanHouseBuilder();,建造者模式分析,建造者模式的使用使产品内部表象可以独立变化;可以使客户端不必知道产品内部组成细节每一个Builder都相对独立,与其它Builder无关可对构造过程更加精细控制将构建代码和表示代码分开缺点:难于应付“分步骤构建算法”的需求变动,单件(Singleton)模式的由来,单件模式的实例较为普遍:系统中只能有一个窗口管理器系统中只能有一个文件系统一个数字滤波器只能有一个A/D转换器一个会计系统只能用于一个公司,单件模式的由来,如何才能保证一个类只有一个实例并且这个实例易于被访问呢?全局变量使得一个对象可以被访问,但不能防止实例化多个对象更好的办法:让类自身保存其唯一实例,可以保证该类没有其他实例可以被创建,并且它可以提供一个访问该实例的方法,单件模式的意图和适用性,意图:保证一个类仅有一个实例,并提供一个全局访问点适用场合:当类只能有一个实例而且需要使用户可从一个统一访问点访问它时当这个唯一实例通过子类化可扩展,并且客户应该无需更改代码就能使用一个扩展实例时,单件模式的结构,Singleton:被调用的单件对象定义一个Instance操作,允许客户访问它的唯一实例。Instance是一个类操作(静态成员函数),负责创建自己的唯一实例,单件模式的应用示例,ClassSingleton/单件模式的定义public:staticSingleton*Instance();/通过该成员函数访问单件protected:Singleton();/构造函数为受保护型,直接实例化将出错private:staticSingleton*_instance;/指向本身唯一实例的指针;,单件模式的应用示例,Singleton*Singleton:_instance=0;/初始化类成员Singleton*Singleton:Instance()If(_instance=0)_instance=newSingleton;return_instance;,单件模式的效果分析,可实现对唯一实例的受控访问:因为Singleton类封装唯一实例,所以它可以严格的控制客户怎样以及何时访问它缩小了名空间:Singleton模式是对全局变量的一种改进。它避免了那些存储唯一实例的全局变量污染名空间,原型(Prototype)模式的由来,在软件系统中,客户希望创建一个产品时,可能有三种情况:知道产品具体型号:使用new运算符创建不知道产品型号,知道特定的需求:使用工厂模式不知道需求,但想要一个和已知对象相同的对象:使用原型模式,原型(Prototype)模式的意图和适用性,意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象适用性:一个系统独立于其产品创建,构成和表示时要实例化的类在运行时刻指定时为避免创建一个与产品类层次平行的工厂类层次时,原型模式的结构,Client:客户端向原型管理器提出创建对象请求Prototype:是对各种具体原型的抽象,通常由一个接口或抽象类实现ConcretePrototype:被复制的对象。此角色需要实现抽象的原型角色所要求的接口PrototypeManager:创建具体原型类的对象,记录每一个被创建的对象,原型模式的参与者,开发一个调色板,用户单击调色板上任一个方块,返回一个对应颜色的实例把每种颜色作为一个对象,并为他们抽象出一个公共父类,原型模式应用示例,原型模式应用示例,优点(1)对客户隐藏具体产品类,减少了客户知道的名字的数目(2)允许客户只通过注册原型实例就可以将一个具体产品类并入系统中,客户可以在运行时刻建立和删除原型(3)具有给一个应用软件动态加载新功能的能力。由于其独立性较高,可以很容易动态加载新功能而不影响老系统(4)产品类不需要非得有任何事先确定的等级结构,适用于任何的等级结构缺点Prototype模式的最主要缺点就是每个类必须配备一个克隆方法,原型模式的应用效果分析,工厂模式是一种极端情况下的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的一种推广工厂模式的特点一个抽象产品类,可以派生出多个具体产品类一个抽象工厂类,可以派生出多个具体工厂类每个具体工厂类只能创建一个具体的产品类实例抽象工厂模式的特点多个抽象产品类,每个抽象产品类可以派生出多个具体产品类一个抽象工厂类,可以派生出多个具体工厂类每个具体工厂类可以创建多个具体产品类的实例,抽象工厂模式与工厂模式的区别,抽象工厂允许客户使用抽象接口来创建一组相关产品,而不需要关心具体产出产品是什么总结所有工厂都是用来封装对象的创建简单工厂,可以把客户程序从具体类解耦工厂方法使用继承,把对象创建委托给子类,子类实现工厂方法来创建对象抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中所有工厂模式都通过减少应用程序与具体类之间的依赖关系促进松耦合工厂方法允许类将实例化延迟到子类进行抽象工厂创建相关的家族,而不需要依赖他们的具体类工厂帮助我们针对抽象编程,而不是针对具体类编程,抽象工厂模式与工厂模式的区别,工厂模式:定义一个创建对象的接口,由子类决定要实例化的具体类,工厂方法让类把实例化推迟到子类抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类建造者模式:封装一个产品(复杂对象)的构造过程,并允许按照步骤构造,向客户隐藏了产品的内部表现单件模式:确保一个类只有一个实例,并提供全局访问点原型模式:当创建给定类实例的过程很昂贵或很复杂时,使用原型模式,向客户隐藏制造新实例的复杂性,创建型设计模式总结,结构型设计模式,适配器模式外观模式装饰模式桥接模式享元模式代理模式组合模式,结构型模式的主要内容,软件开发过程中常见的问题,系统组件更新问题:软件系统的某组件过时了,要从厂商那里引进一个新的组件,但原系统的组件接口和新组件的接口不一致,同时又不想改变现有的代码,如何实现从旧组件更新到新组件,两个接口无法匹配,所以无法工作,软件开发过程中常见的问题,生活中相似问题的解决方案不合适的插座问题电脑的插头是三相的墙上的插座只有两相的插头和插座的“接口”不匹配,怎么办?,组件更新问题的可行解决方案,两个接口无法匹配,所以无法工作,适配器模式的动机,一个team要为外界提供S类服务,但team里面没有能够完成此项任务的member,只有team外的A可以完成这项服务。为保证对外服务类别的一致性(能提供S服务)将A招安到team内,负责提供S类服务A不准备接受招安,可安排B去完成这项任务,并让B做好A的工作,让B工作的时候向A请教,此时,B是一个复合体(提供S服务,是A的继承弟子)动机:将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以一起工作,适配器模式使用过程,客户(Client)通过目标接口调用适配器(Adapter)的方法对适配器发出请求适配器(Adapter)使用被适配者(Adaptee)接口把请求转换成被适配者的一个或者多个调用接口客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用,适配器模式的适用性,适用场合:使用一个已经存在的类,而它的接口不符合要求创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作使用一些已经存在的子类,但不可能通过子类化以匹配各自接口。对象适配器可以适配它的父类接口分类:类适配器:通过多重继承匹配一个接口和另一个接口对象适配器:在一个类中定义另一个类的实例对象,实现类和对象的组合,类适配器,用一个具体的Adapter类对Adaptee和Target进行匹配,Adapter类多重继承Adaptee和Target类Adapter可重定义Adaptee的部分行为,因为Adapter是Adaptee的一个子类,类适配器模式示例,/Target:定义Client使用的与特定领域相关的接口publicinterfaceTargetvoidrequest();,/Adaptee:需要适配的已经存在的接口publicclassAdapteepublicvoidspecificRequest(),/Adapter:对Adaptee的接口与Target接口进行适配publicclassAdapterextendsAdapteeimplementsTargetpublicvoidrequest()super.specificRequest();,对象适配器,允许一个Adapter与多个Adaptee同时工作,即Adaptee本身以及它的所有子类(如果有子类的话)同时工作。Adapter可以一次给所有的Adaptee添加功能使用组合,不仅可以适配某个类,也可以适配该类的任何子类,对象适配器模式示例,/Target:定义Client使用的与特定领域相关的接口publicinterfaceTargetvoidrequest();,/Adaptee:现在需要适配的已经存在的接口publicclassAdapteepublicvoidspecificRequest(),/Adapter:对Adaptee的接口与Target接口进行适配publicclassAdapterimplementsTargetprivateAdapteeadaptee;publicAdapter(Adapteeadaptee)super();this.adaptee=adaptee;publicvoidrequest()adaptee.specificRequest();,适配器模式效果分析,优点方便设计者自由定义接口,不用担心匹配问题缺点属于静态结构,由于只能单继承,所以不适用于多种不同的源适配到同一个目标,两种适配器模式的比较,外观(Facade)模式的由来,毕业生,教务处,公安处,后勤处,图书馆,饭卡,饭卡余额,借书证,借书证押金,身份证、学生证,派遣证,学生证,毕业证、学位证,外观(Facade)模式的由来,毕业生,毕业手续代办处,教务处,后勤处,图书馆,公安处,学生证身份证借书证饭卡,毕业证学位证派遣证饭卡余额借书证押金,外观(Facade)模式的由来,外观(Faade)模式的由来,外观(Facade)模式的意图和适用性,提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用解除客户程序对抽象类具体实现部分的依赖,有利于移植和更改当需要构建层次结构的子系统时,使用Faade模式定义每层入口点。如果子系统间相互依赖,只需通过Faade进行通讯外观模式的本质是让接口变得更简单,外观(Facade)模式的结构,外观(Facade)模式的参与者,Faade知道哪些子系统类负责处理请求将客户的请求代理给适当的子系统对象SubsystemClasses实现子系统的功能处理由Faade对象指派的任务没有Faade的任何相关信息,外观(Facade)模式的效果分析,根据“单一职责原则”,在软件中将一个子系统划分为若干个子系统有利于降低整个系统的复杂性,一个常见的设计目标是使子系统之间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口外观模式也是“迪米特法则”的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度,外观(Facade)模式的效果分析,外观模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道外观模式的目的在于降低系统的复杂程度外观模式从很大程度上提高了客户端使用的便捷性,使得客户端无须关心子系统的工作细节,通过外观角色即可调用相关功能如何增加新的子系统?是否可能违背“开闭原则”,外观(Facade)模式的缺点,不能很好的限制客户使用子系统类,如果对客户访问子系统类做太多的限制,则减少了可变形和灵活性增加一个新的子系统,可能需要修改外观类或客户端的源代码,违背了“开闭原则”,怎么办?引入抽象外观类,客户端针对抽象外观类编程,装饰(Decorator)解决的问题,新买一辆车,但外表不够美观,对车的外表进行必要的装饰,装饰(Decorator)模式的由来,动态给对象添加额外职责。比如:一幅画有没有画框都可以挂在墙上,画是被装饰者。在挂在墙上之前,画可以被蒙上玻璃,装到框子里,玻璃画框就是装饰不改变接口,但加入了责任。Decorator提供了一种给类增加职责的方法,不是通过继承,而是通过组合实现的,装饰(Decorator)模式的意图和适用性,意图动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式比生成子类更为灵活适用场合在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立扩展,每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况是因为类定义被隐藏,或类定义不能用于生成子类,装饰(Decorator)模式的结构,Component:定义对象的接口,可以给对象动态添加职责ConcreteComponent:定义具体对象,装饰抽象类可以给它添加额外的职责Decorator:维持一个指向Component对象的指针,并定义一个与Component接口一致的接口ConcreteDecorator:具体装饰对象,向具体对象添加职责Decorator将请求转发给它的Component对象,并有可能在转发请求前后执行一些附加的动作,装饰(Decorator)模式的结构,装饰(Decorator)模式的应用,Component,ConcreteComponent,装饰(Decorator)模式的应用,Decorator,装饰(Decorator)模式的应用,ConcreteDecorator,装饰(Decorator)模式的应用,装饰(Decorator)模式的评价,使用Decorator模式可以很容易地向对象添加职责。可以用添加和分离的方法,在运行时添加和删除职责使用Decorator模式可以很容易地重复添加一个特性,而两次继承则极容易出错避免在层次结构高层的类有太多的特征:可以从简单的部件组合出复杂的功能。具有低依赖性和低复杂性,桥接(Bridge)模式的由来,例子:设想如果要绘制矩形、圆形、椭圆、正方形,至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案为每一种形状都提供一套各种颜色的版本根据实际需要对形状和颜色进行组合,桥接(Bridge)模式的由来,1,2,方案表示桥接模式,将继承关系转换为关联关系,降低了类与类之间的耦合,减少了代码量,桥接(Bridge)模式的由来,例子:相同模块的跨平台使用设计模块A和B希望模块A和B能应用在X操作系统上,让A和B继承X操作系统的接口希望模块A和B能应用在Y操作系统上,让A和B继承Y操作系统的接口,以此类推问题:模块A和B缺乏复用性解决:抽象出统一的操作系统类的接口连接模块A和B的平台无关接口,通过桥接两个抽象模块来消除模块间的继承耦合,提高复用性,扩展Window抽象使之用于不同种类的窗口或新的平台很不方便,继承机制使得客户代码与平台相关,桥接(Bridge)模式的由来,1,将Window抽象和它的实现部分分别放在独立的类层次结构中,针对窗口接口,针对平台的窗口实现,桥接(Bridge)模式的由来,2,对于有两个变化维度(即两个变化的原因)的系统,采用方案二进行设计,系统中类的个数更少,且系统扩展更为方便设计方案二即是桥接模式的应用。桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码量,桥接(Bridge)模式的动机,桥接(Bridge)模式的意图和适用性,意图:桥接模式的作用就是将抽象部分与实现部分分离,使它可以独立的变化适用的情况不希望在抽象和它的实现部分之间有一个固定的绑定关系想对客户完全隐藏抽象的实现部分,桥接(Bridge)模式的结构,桥接(Bridge)模式的参与者,Abstraction定义抽象类的接口维护一个指向Implementor类型对象的指针RefinedAbstraction扩充由Abstraction定义的接口Implementor定义实现类的接口,不一定要与Abstraction的接口完全一致,甚至可以完全不同ConcreteImplementor实现Implementor接口并定义它的具体实现Abstraction将Client的请求转发给它的Implementor对象,桥接(Bridge)模式的意义,脱耦是指将抽象和实现之间的耦合解脱开,或者说将他们之间的强关联改成若弱关联强关联是指在编译时期已经确定的,无法在运行时期动态改变的关联弱关联是可以动态确定并可在运行时刻动态改变的关联继承关系是强关联,聚合关系是弱关联,将两个角色之间的继承关系修改为聚合关系,就是将他们之间的强关联变换成弱关联。桥模式中的所谓脱耦就是指在一个软件系统的抽象和实现之间使用组合/聚合关系而不是继承关系,从而可以使两者可以相对独立的变化,桥接(Bridge)模式的优点,分离抽象接口及其实现部分桥接模式有时类似于多继承方案,但是多继承方案违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差,而且多继承结构中类的个数非常庞大,桥接模式是比多继承方案更好的解决方法桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统实现细节对客户透明,可以对用户隐藏实现细节,桥接(Bridge)模式的缺点,桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性,桥接(Bridge)模式的应用案例,桥接(Bridge)模式的应用案例,享元(Flyweght)模式的由来,享元(Flyweght)模式的由来,当大量使用同一种类型的实例(每个实例中包含部分相同的数据),可能极大的耗费资源,使用Flyweight模式可以提高内存效率以CD唱片为例,每个CD有三个属性:出片日期、歌唱者姓名、唱片曲目姓名可能重复,可能有同一个演唱者的多个不同时期不同曲目的CD。歌唱者姓名可共享,其他字段均不可共享当你有几千张甚至更多CD时,Flyweight模式将节省更多空间,共享的flyweight越多,空间节省也就越大,享元(Flyweght)模式的意图和适用性,意图:避免大量拥有相同内容的小类的开销,共享一元类动机:通过共享技术实现相同或相似对象的重用适用性一个应用程序使用了大量的对象冗余使用了大量的对象,造成了很大的存储开销,享元(Flyweght)模式的结构,享元(Flyweght)模式的参与者,Flyweight:描述一个接口,可接受并作用于外部状态ConcreteFlyweight:实现Flyweight接口,并为内部状态增加存储空间。必须是可共享的,存储的状态必须是内部的UnsharedConcreteFlyweight:不强制共享FlyweightFactory:创建并管理flyweight对象;确保合理地共享flyweight,提供已创建的flyweight实例或者创建一个Client:维持一个对flyweight的引用;计算或存储一个(多个)flyweight的外部状态,享元(Flyweght)模式的参与者,Flyweight执行时所需的状态必定是内部或外部的。内部状态存储在ConcreteFlyweight中,外部对象则由Client对象存储或计算。当用户调用flyweight对象操作时,将该状态传递给它用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight对象,以保证对它们适当地进行共享,享元(Flyweght)模式的效果分析,Flyweight模式的核心就是把大量共享的对象收集在一起使用简单工厂模式进行管理,避免由于大量的小对象导致系统的内存过渡消耗当重复对象较多时,Flyweight模式具有较好的空间性能,但在查找搜索上消耗了时间复杂度,代理(Proxy)模式的几个来源,代理(Proxy)模式的由来,某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动如果对象是一个大图片,需要花费很长时间才能显示出来,此时需要做个图片Proxy来代替真正的图片如果对象在某远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,可以用Proxy来代替那个对象如何应对这种变化?如何提供一种机制让原本交互起来比较困难的两个对象实现畅通无阻地交流呢?如何保持系统的结构不随着需求改变而轻易改变?这就是代理模式,代理(Proxy)模式的意图和适用性,意图:为其他对象提供一种代理以控制对这个对象的访问适用性:远程代理为一个对象在不同的地址空间提供局部代表虚代理在需要创建开销很大对象时缓存对象信息保护代理控制对原始对象的访问,代理(Proxy)模式的结构,代理(Proxy)模式的参与者,Proxy保存一个引用使得代理可以访问实体提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体控制对实体的存取,并可能负责创建和删除它其他功能依赖于代理的类型Subject定义ConcreteSubject和Proxy的共用接口,在任何使用ConcreteSubject的地方都可以使用ProxyConcreteSubject定义Proxy所代表的实体,代理(Proxy)模式的应用示例,一个简单的数学计算程序,程序只负责简单的加减乘除运算,代理(Proxy)模式的效果分析,RemoteProxy为一个位于不同地址空间的对象提供一个局域代表对象将网络细节隐藏,客户端不必考虑网络的存在代理对象承担了大部份的网络通讯工作VirtualProxy创建一个资源消耗较大的对象,需要时才被真正创建代理对象可以在必要的时候才加载被代理对象代理可以对加载的过程加以优化,代理(Proxy)模式的效果分析,ProtectProxy控制对象的访问,可给不同用户提供不同级别的使用权限可以在运行时对用户权限进行检查CacheProxy为目标操作提供临时存储空间,以便多客户端共享FirewallProxy保护目标,防止恶意用户接近SynchronizationProxy使多用户能同时使用一个对象而没有冲突,组合(Composite)模式的由来,表达部分与整体的树形结构,组合(Composite)模式的由来,抽象单一对象(Leaf):键盘、鼠标、显示器、硬盘、电源、CPU、显卡、网卡组合对象(Composite):计算机、机箱、主板部件(Component):单一对象与组合对象的统称组合对象既可以包括单一对象,也可以包括组合对象,组合(Composite)模式的意图和适用性,意图:将对象组合成树形结构,表示“部分/整体”层次结构使用户对单一对象和组合对象使用一致性接口适用性表示对象的部分-整体层次结构忽略总体对象与单一对象差异,统一使用组合结构的所有对象,组合(Composite)模式的结构,组合(Composite)模式的参与者,Component为组合对象声明接口声明一个接口用于访问和管理Component的子组件Leaf表示叶节点对象,没有子节点定义图元对象的行为Composite定义复合部件的行为存储子部件Client通过Component接口操纵组合部件的对象,组合(Composite)模式的效果,定义了包含基本对象和组合对象的类层次结构简化客户代码,一致使用组合对象和单个对象容易增加新类型的组件用户使用Component类接口与组合结构中的对象进行交互。如果接收者是叶节点,直接处理请求;如果接收者是Composite,将请求发送给它的子部件,在转发请求之前和/或之后可能执行一些辅助操作,组合(Composite)模式案例,文件系统(浏览不同类型的文件),组合(Composite)模式案例,水果盘问题:在水果盘(Plate)中有一些水果,如苹果(Apple)、香蕉(Banana)、梨子(Pear),当然大水果盘中还可以有小水果盘,现需要对盘中的水果进行遍历(吃),当然如果对一个水果盘执行“吃”方法,实际上就是吃其中的水果。,组合(Composite)模式案例,结构型设计模式总结,Adapter、Bridge、FacadeAdapter用于两个已有的不兼容接口之间的转接Bridge用于将一个抽象与多个可能的实现进行桥接Facade用于为复杂的子系统定义一个新的简单易用的接口Composite、Decorator和ProxyComposite用于构造对象(递归)组合结构Decorator用于为对象增加新的职责Proxy为目标对象提供一个替代者Flyweight针对细粒度对象的一种全局控制手段,行为型设计模式,模板模式(TemplatemethodPattern)观察者模式(ObserverPattern)迭代
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 环保责任的企业战略导向
- 企业参与高等教育课程设置的优势与难点
- 虚拟现实与增强现实在生产过程中的应用
- 教联体的创新模式与实践路径
- 城市品牌塑造中的影视产业参与作用
- 青少年急救知识教育的跨学科整合与创新
- 春节游戏盈收攻略
- 成长的蓝图模板
- 低血糖危象患者护理查房
- 儿童青春期心理健康教育
- 煤矸石综合利用工程项目可行性研究报告
- 沉降差法检测土石路堤压实度分析
- 2024年四川省南充市中考英语试卷真题(含官方答案及解析)
- 【真题】2024年常州市中考英语试卷(含答案解析)
- 动物解剖学-心血管系统课件
- 2024全国能源行业火力发电集控值班员理论知识技能竞赛题库(多选题)
- JGT 352-2017 现浇混凝土空心结构成孔芯模
- 第18讲 八下课标文言文复习(练习)-2024年中考语文一轮复习讲练测(全国)(原卷版)
- 山东省济南市平阴县2023-2024学年八年级下学期期末数学试题
- 2024全新股份合作协议样板下载
- 砾岩和角砾岩课件
评论
0/150
提交评论