设计模式浅谈种_第1页
设计模式浅谈种_第2页
设计模式浅谈种_第3页
设计模式浅谈种_第4页
设计模式浅谈种_第5页
已阅读5页,还剩135页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

设计模式浅谈种第1页,共140页,2023年,2月20日,星期日准备——理解面向对象设计的原则开放-封闭原则:是说软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。里氏代换原则:子类型必须能够替换掉它们的父类型。依赖倒转原则:A.高层模块不应该依赖低层模块。两个都应该依赖抽象。B.抽象不应该依赖细节。细节应该依赖抽象。请参考《面向对象设计的原则》2第2页,共140页,2023年,2月20日,星期日概述导致重新设计的一般原因通过显式指定一个类来创建对象对特殊操作的依赖对硬件和软件平台的依赖对对象表示和实现的依赖对算法的依赖紧耦合通过生成子类来扩充功能不能方便地对类进行修改3第3页,共140页,2023年,2月20日,星期日概述4原则一:对接口编程,而不是对实现编程原则二:优先使用对象组合,而不是继承第4页,共140页,2023年,2月20日,星期日概述什么是设计模式设计模式是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动。设计模式的内容模式名称Patternname问题Problem解决方案Solution效果Consequences5第5页,共140页,2023年,2月20日,星期日概述设计模式编目范围目的创建型结构型行为型类FactoryMethodAdapterInterpreterTemplateMethod对象AbstractFactoryBuilderPrototypeSingletonAdapterBridgeCompositeDecoratorFacadeFlyweightProxyChainofResponsibilityCommandIteratorMediatorMementoObserverStateStrategyVisitor第6页,共140页,2023年,2月20日,星期日设计模式之间的关系7第7页,共140页,2023年,2月20日,星期日创建型模式创建型模式的目的使系统独立于如何创建、组合和表示对象。类创建型模式使用继承改变被实例化的类。对象创建型模式将实例化委托给另一个对象。8AbstractFactoryBuilderFactoryMethodPrototypeSingleton第8页,共140页,2023年,2月20日,星期日创建型模式三种Factory模式:SimpleFactory(简单工厂)模式:专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类。FactoryMethod(工厂方法)模式:将对象的创建交由父类中定义的一个标准方法来完成,而不是其构造函数,究竟应该创建何种对象由具体的子类负责决定。AbstractFactory(抽象工厂)模式:提供一个共同的接口来创建相互关联的多个对象。9第9页,共140页,2023年,2月20日,星期日创建型模式FactoryMethod(工厂方法)类创建型模式意图定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。适用性当一个类不知道它所必须创建的对象的类的时候。当一个类希望由它的子类来指定它所创建的对象的时候。当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。10第10页,共140页,2023年,2月20日,星期日创建型模式FactoryMethod(工厂方法)11第11页,共140页,2023年,2月20日,星期日创建型模式FactoryMethod(工厂方法)效果用工厂方法在类中创建对象比直接创建更灵活,子类可以提供对象的扩展版本。连接平行的类层次,将哪些类应一同工作的信息局部化。实现Creator可以只声明工厂方法,也可以提供缺省的实现。可以使用模板以避免创建子类。可采用适当的命名约定说明正在使用工厂方法。12第12页,共140页,2023年,2月20日,星期日创建型模式AbstractFactory(抽象工厂)对象创建型模式意图提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。适用性一个系统要独立于它的产品的创建、组合和表示时。一个系统要用多个产品系列中的一个来配置时。要强调一系列相关的产品对象的设计以便进行联合使用时。提供一个产品类库,而只想显示它们的接口而不是实现时。13第13页,共140页,2023年,2月20日,星期日创建型模式AbstractFactory(抽象工厂)14第14页,共140页,2023年,2月20日,星期日创建型模式15第15页,共140页,2023年,2月20日,星期日创建型模式AbstractFactory(抽象工厂)效果由工厂封装产品对象的创建,将客户与类的实现分离。易于交换产品系列。有利于产品的一致性。难以支持新种类的产品。实现通常可以将工厂作为Singleton。AbstractFactory声明创建产品的接口,由工厂子类负责创建产品,通常为每个产品定义一个工厂方法。一种更灵活但不太安全的设计是以参数方式创建对象。16第16页,共140页,2023年,2月20日,星期日创建型模式Builder(生成器)对象创建型模式意图将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。适用性当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。当构造过程必须允许被构造的对象有不同的表示时。17第17页,共140页,2023年,2月20日,星期日创建型模式Builder(生成器)18第18页,共140页,2023年,2月20日,星期日创建型模式四个角色:建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。具体建造者(ConcreteBuilder)角色:担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:实现Builder角色提供的接口,一步一步完成创建产品实例的过程。在建造过程完成后,提供产品的实例。19第19页,共140页,2023年,2月20日,星期日创建型模式指导者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。产品(Product)角色:产品便是建造中的复杂对象。指导者角色是于客户端打交道的角色。导演者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但却不为客户端所知。20第20页,共140页,2023年,2月20日,星期日创建型模式Builder(生成器)21classBuilder{

//创建部件A比如创建汽车车轮

voidbuildPartA();

//创建部件B比如创建汽车方向盘

voidbuildPartB();

//创建部件C比如创建汽车发动机

voidbuildPartC();

//返回最后组装成品结果(返回最后装配好的汽车)

//成品的组装过程不在这里进行,而是转移到下面的Director类中进行.

//从而实现了解耦过程和部件

Product*getResult();};classDirector{

privateBuilder*m_builder;

publicDirector(Builder*builder){

m_builder=builder;

}

//将部件partApartBpartC最后组成复杂对象

//这里是将车轮方向盘和发动机组装成汽车的过程

publicvoidconstruct(){

builder->buildPartA();

builder->buildPartB();

builder->buildPartC();

}};classConcreteBuilder:publicBuilder{

PartpartA,partB,partC;public:

voidbuildPartA(){

//这里是具体如何构建partA的代码

}

voidbuildPartB(){

//这里是具体如何构建partB的代码

}

voidbuildPartC(){

//这里是具体如何构建partB的代码

}

Product*getResult(){

//返回最后组装成品结果

}

};ConcreteBuilderbuilder;

Directordirector(&builder);

director.construct();

Product*product=builder.getResult();第21页,共140页,2023年,2月20日,星期日创建型模式Builder(生成器)效果可以改变一个产品的内部表示。将构造代码和表示代码分开。可以对构造过程进行更精细的控制。实现Builder类接口应足够普遍。产品通常不需要有公共抽象类。Builder中通常缺省方法为空。22第22页,共140页,2023年,2月20日,星期日创建型模式Prototype(原型)对象创建型模式意图用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。适用性当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者为了避免创建一个与产品类层次平行的工厂类层次时;或者当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。23第23页,共140页,2023年,2月20日,星期日创建型模式Prototype(原型)24第24页,共140页,2023年,2月20日,星期日创建型模式客户(Client)角色:客户类提出创建对象的请求。抽象原型(Prototype)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体原型类所需的接口。具体原型(ConcretePrototype)角色:被复制的对象。此角色需要实现抽象原型角色所要求的接口。25第25页,共140页,2023年,2月20日,星期日创建型模式Prototype(原型)效果可在运行时刻增加和删除产品。可以通过改变值来指定新产品。可以通过改变结构来指定新对象。减少了子类的构造。可以用类动态配置应用。实现使用一个原型管理器;实现克隆操作(浅拷贝和深拷贝);初始化克隆对象;参考阎宏的《JAVA模式》26第26页,共140页,2023年,2月20日,星期日创建型模式Singleton(单件)对象创建型模式意图保证一个类仅有一个实例,并提供一个访问它的全局访问点。适用性当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。27第27页,共140页,2023年,2月20日,星期日创建型模式Singleton(单件)28实例详解第28页,共140页,2023年,2月20日,星期日结构型模式结构型模式的目的结构型模式涉及到如何组合类和对象以获得更大的结构。结构型类模式采用继承机制来组合接口或实现。结构型对象模式描述了如何对一些对象进行组合实现新功能,并可以在运行时刻改变对象组合关系的一些方法。29AdapterBridgeCompositeDecoratorFacadeFlyweightProxy第29页,共140页,2023年,2月20日,星期日结构型模式Adapter(适配器)类/对象结构型模式意图将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适用性你想使用一个已经存在的类,而它的接口不符合你的需求。你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。30第30页,共140页,2023年,2月20日,星期日结构型模式角色:目标(Target)角色:这是客户所期待的接口。因为C#不支持多继承,所以Target必须是接口,不可以是类。源(Adaptee)角色:需要适配的类。适配器(Adapter)角色:把源接口转换成目标接口。根据这一角色的实现不同,可分为类适配器和对象适配器。31第31页,共140页,2023年,2月20日,星期日结构型模式Adapter(类适配器)类适配器是通过继承类适配者类(Adaptee

Class)实现的,另外类适配器实现客户类所需要的接口。当客户对象调用适配器类方法的时候,适配器内部调用它所继承的适配者的方法。32第32页,共140页,2023年,2月20日,星期日结构型模式Adapter(对象适配器)对象适配器包含一个适配器者的引用(reference),与类适配器相同,对象适配器也实现了客户类需要的接口。当客户对象调用对象适配器的方法的时候,对象适配器调它所包含的适配器者实例的适当方法。

33实例详解第33页,共140页,2023年,2月20日,星期日结构型模式Bridge(桥接)对象结构型模式意图将抽象部分与它的实现部分分离,使它们都可以独立地变化。通过动态的结合实现解耦(GOF).比如说通过JDBC访问数据库,我们操作的API是基于接口的,是抽象,没有实现。而特定数据库提供的驱动测试抽象方法的具体实现。适用性34第34页,共140页,2023年,2月20日,星期日结构型模式Bridge(桥接)对象结构型模式意图适用性不希望在抽象和它的实现部分之间有一个固定的绑定关系。类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。你想对客户完全隐藏抽象的实现部分。有许多子类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。35第35页,共140页,2023年,2月20日,星期日结构型模式Bridge(桥接)36第36页,共140页,2023年,2月20日,星期日结构型模式角色:抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。37第37页,共140页,2023年,2月20日,星期日结构型模式Bridge(桥接)效果分离了接口及其实现部分。提高了可扩充性。实现了细节对客户透明。实现当仅有一个Implementor时不须创建抽象Implementor。如何创建正确的Implementor对象。共享Implementor对象。38第38页,共140页,2023年,2月20日,星期日结构型模式Composite(组合)对象结构型模式意图将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。适用性你想表示对象的部分-整体层次结构。你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。2014年9月29日22时40分39第39页,共140页,2023年,2月20日,星期日结构型模式Composite(组合)40第40页,共140页,2023年,2月20日,星期日结构型模式角色:抽象构件(Component)角色:这是一个抽象角色,它给参与组合的对象规定一个接口。这个角色给出共有接口及其默认行为。树叶构件(Leaf)角色:代表参加组合的树叶对象。一个树叶对象没有下级子对象。树枝构件(Composite)角色:代表参加组合的有子对象的对象,并给出树枝构件对象的行为。可以看出,Composite类型的对象可以包含其它Component类型的对象。换而言之,Composite类型对象可以含有其它的树枝(Composite)类型或树叶(Leaf)类型的对象。41第41页,共140页,2023年,2月20日,星期日结构型模式Decorator(装饰),又名包装(Wrapper)模式对象结构型模式意图动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。适用性42第42页,共140页,2023年,2月20日,星期日结构型模式Decorator(装饰)对象结构型模式意图适用性在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。处理那些可以撤消的职责。当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。43第43页,共140页,2023年,2月20日,星期日结构型模式Decorator(装饰)44第44页,共140页,2023年,2月20日,星期日结构型模式角色有:抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。具体装饰(ConcreteDecorator)角色:负责给构件对象"贴上"附加的责任。45第45页,共140页,2023年,2月20日,星期日结构型模式孙悟空有七十二般变化,他的每一种变化都给他带来一种附加的本领。他变成鱼儿时,就可以到水里游泳;他变成雀儿时,就可以在天上飞行。而不管悟空怎么变化,在二郎神眼里,他永远是那只猢狲。装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。46第46页,共140页,2023年,2月20日,星期日结构型模式装饰模式使用原来被装饰的类的一个子类的实例,把客户端的调用委派到被装饰类。装饰模式的关键在于这种扩展是完全透明的。在孙猴子的例子里,老孙变成的鱼儿相当于老孙的子类,这条鱼儿与外界的互动要通过“委派”,交给老孙的本尊,由老孙本尊采取行动。47第47页,共140页,2023年,2月20日,星期日结构型模式Decorator(装饰)48第48页,共140页,2023年,2月20日,星期日结构型模式Decorator(装饰)效果Decorator比静态继承更灵活;Decorator避免在层次结构高层的类中有太多的特征;Decorator不等同于它所装饰的对象;可能产生很多小对象;实现装饰对象应与被装饰组件保持一致的接口,即组件的所有装饰实现类拥有相同的父类;当只有一个装饰实现类时,可省略装饰抽象类;组件与装饰拥有相同父类,应保持该父类的简单性;装饰可以用于改变组件的外观,而不能改变组件的内核;49第49页,共140页,2023年,2月20日,星期日结构型模式Decorator(装饰)50第50页,共140页,2023年,2月20日,星期日结构型模式Facade(外观)对象结构型模式意图为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。适用性51第51页,共140页,2023年,2月20日,星期日结构型模式Facade(外观)对象结构型模式意图适用性为一个复杂子系统提供一个简单接口,需要更多的可定制性的用户可以越过Facade层。当客户程序与抽象类的实现部分之间存在着很大的依赖性时,引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。在构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点。让相互依赖的子系统之间仅通过Facade进行通讯,可以简化它们之间的依赖关系。52第52页,共140页,2023年,2月20日,星期日结构型模式Facade(外观)53第53页,共140页,2023年,2月20日,星期日结构型模式两个角色:门面(Facade)角色:客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。子系统(subsystem)角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。54第54页,共140页,2023年,2月20日,星期日结构型模式Facade(外观)55第55页,共140页,2023年,2月20日,星期日结构型模式Facade(外观)56第56页,共140页,2023年,2月20日,星期日结构型模式Flyweight(享元)对象结构型模式意图运用共享技术有效地支持大量细粒度的对象。适用性57第57页,共140页,2023年,2月20日,星期日结构型模式Flyweight(享元)对象结构型模式意图适用性应用程序使用了大量的对象,造成很大的存储开销。对象的大多数状态都可变为外部状态。如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。应用程序不依赖于对象标识。由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。58第58页,共140页,2023年,2月20日,星期日结构型模式享元模式以共享的方式高效地支持大量的细粒度对象。享元对象能做到共享的关键是区分内蕴状态(InternalState)和外蕴状态(ExternalState)。内蕴状态是存储在享元对象内部并且不会随环境改变而改变。因此内蕴状态并可以共享。外蕴状态是随环境改变而改变的、不可以共享的状态。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外蕴状态与内蕴状态是相互独立的。59第59页,共140页,2023年,2月20日,星期日结构型模式Flyweight(享元)60第60页,共140页,2023年,2月20日,星期日结构型模式角色如下:抽象享元(Flyweight)角色:此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口。那些需要外蕴状态(ExternalState)的操作可以通过调用商业方法以参数形式传入。具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享的。61第61页,共140页,2023年,2月20日,星期日结构型模式复合享元(UnsharableFlyweight)角色:复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。复合享元角色又称做不可共享的享元对象。62第62页,共140页,2023年,2月20日,星期日结构型模式享元工厂(FlyweightFactory)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个复合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。客户端(Client)角色:本角色需要维护一个对所有享元对象的引用。本角色需要自行存储所有享元对象的外蕴状态。63第63页,共140页,2023年,2月20日,星期日结构型模式享元模式的应用享元模式在编辑器系统中大量使用。一个文本编辑器往往会提供很多种字体,而通常的做法就是将每一个字母做成一个享元对象。享元对象的内蕴状态就是这个字母,而字母在文本中的位置和字模风格等其他信息则是外蕴状态。比如,字母a可能出现在文本的很多地方,虽然这些字母a的位置和字模风格不同,但是所有这些地方使用的都是同一个字母对象。这样一来,字母对象就可以在整个系统中共享。64第64页,共140页,2023年,2月20日,星期日结构型模式Flyweight(享元)65第65页,共140页,2023年,2月20日,星期日结构型模式享元模式的优点和缺点享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的:享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。66第66页,共140页,2023年,2月20日,星期日结构型模式Proxy(代理)对象结构型模式意图为其他对象提供一种代理以控制对这个对象的访问。适用性在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。67第67页,共140页,2023年,2月20日,星期日结构型模式代理的种类——如果按照使用目的来划分,可分为:远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。68第68页,共140页,2023年,2月20日,星期日结构型模式保护(ProtectorAccess)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。防火墙(Firewall)代理:保护目标,不让恶意用户接近。同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。智能引用(SmartReference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。69第69页,共140页,2023年,2月20日,星期日结构型模式Proxy(代理)70第70页,共140页,2023年,2月20日,星期日结构型模式角色:抽象主题角色(Subject):声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题。真实主题角色(RealSubject)角色:定义了代理角色所代表的真实对象。71第71页,共140页,2023年,2月20日,星期日结构型模式角色:代理主题(Proxy)角色:代理主题角色内部含有对真是主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主体;控制真实主题的应用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯的将调用传递给真实主题对象。72第72页,共140页,2023年,2月20日,星期日结构型模式Proxy(代理)73第73页,共140页,2023年,2月20日,星期日结构型模式结构型模式的讨论Adapter和Bridge都涉及到从自身以外的接口向另一对象发送请求,Adapter是为了解决两个接口不匹配,Bridge则是对抽象接口与其实现部分进行桥接。Adapter通常在类设计好之后实施,Bridge则在类设计之前实施。Adapter使两个已经存在的接口协同工作,并不定义新的接口,而Facade则定义了一个新的接口。Composite和Decorator都是基于递归组合来组织可变数目的对象,但Composite的目的是使多个相关对象能够被当作一个对象来处理,Decorator的目的则是不需要生成子类即可给对象添加职责。Decorator和Proxy都描述了为对象提供间接引用,但Proxy不能动态地添加或分离性质,也不是为递归组合而设计的,是由实体完成关键功能,Proxy控制其访问,而Decorator则是在组件基本功能之外完成附加的功能。74第74页,共140页,2023年,2月20日,星期日行为模式行为模式的目的行为模式涉及到算法和对象间职责的分配。行为模式描述对象或类之间的通信模式,刻画了在运行时难以跟踪的复杂的控制流。75ChainofResponsibilityObserverCommandInterpreterIteratorMediatorMementoStateStrategyTemplateMethodVisitor第75页,共140页,2023年,2月20日,星期日行为模式ChainofResponsibility(响应链)对象行为模式意图使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。适用性76第76页,共140页,2023年,2月20日,星期日行为模式ChainofResponsibility(响应链)对象行为模式意图适用性有多个对象可以处理一个请求,哪个对象处理该请求在运行时刻自动确定。在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。可处理一个请求的对象集合应被动态指定。77第77页,共140页,2023年,2月20日,星期日行为模式击鼓传花击鼓传花是一种热闹而又紧张的饮酒游戏。在酒宴上宾客依次坐定位置,由一人击鼓,击鼓的地方与传花的地方是分开的,以示公正。开始击鼓时,花束就开始依次传递,鼓声一落,如果花束在某人手中,则该人就得饮酒。击鼓传花便是责任链模式的应用。责任链可能是一条直线、一个环链或者一个树结构的一部分。78第78页,共140页,2023年,2月20日,星期日行为模式ChainofResponsibility(响应链)79第79页,共140页,2023年,2月20日,星期日行为模式角色如下:抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。80第80页,共140页,2023年,2月20日,星期日行为模式ChainofReponsibility(响应链)81第81页,共140页,2023年,2月20日,星期日行为模式ChainofReponsibility(响应链)效果降低了对象间的耦合度。增强了给对象分配响应(职责)的灵活性。不保证请求被响应。实现后续链的实现请求的表示:硬编码方式或请求码方式82第82页,共140页,2023年,2月20日,星期日行为模式Command(命令)对象行为模式意图将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。适用性83第83页,共140页,2023年,2月20日,星期日行为模式Command(命令)对象行为模式意图适用性抽象出待执行的动作以参数化某对象。Command模式是回调机制的一个面向对象的替代品。在不同的时刻指定、排列和执行请求。支持取消操作。支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。用构建在原语操作上的高层操作构造一个系统。84第84页,共140页,2023年,2月20日,星期日行为模式Command(命令)85第85页,共140页,2023年,2月20日,星期日行为模式角色:客户(Client)角色:创建了一个具体命令(ConcreteCommand)对象并确定其接收者。命令(Command)角色:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色。具体命令(ConcreteCommand)角色:定义一个接受者和行为之间的弱耦合;实现Execute()方法,负责调用接收者的相应操作。Execute()方法通常叫做执方法。86第86页,共140页,2023年,2月20日,星期日行为模式角色:请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。87第87页,共140页,2023年,2月20日,星期日行为模式Command(行为)88第88页,共140页,2023年,2月20日,星期日行为模式Command(命令)效果将调用操作的对象与实现操作的对象解耦。Command对象也可以被操纵和扩展。可以将多个Command装配成一个复合Command。无需改变已有的类,可以容易地增加新Command。实现Command对象的智能程度。对Undo和Redo的支持。避免Undo操作过程中的错误积累。在C++中可以用模板来实现简单的Command类。89第89页,共140页,2023年,2月20日,星期日行为模式Interpreter(解释器)类行为模式意图根据语言的文法,定义一个解释器,用来解释语言中的句子。适用性当有一个语言需要解释执行,并且该语言中的句子可以表示为一个抽象语法树时。

当满足以下情况时,解释器模式的效果最好:文法简单。效率不是一个关键问题。90第90页,共140页,2023年,2月20日,星期日行为模式Interpreter(解释器)91第91页,共140页,2023年,2月20日,星期日行为模式AbstractExpression抽象解释器:声明一个抽象的解释操作,这个接口为所有具体表达式角色(抽象语法树中的节点)都要实现的。具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和NonterminalExpression完成。TerminalExpression终结符表达式:实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。92第92页,共140页,2023年,2月20日,星期日行为模式NonterminalExpression非终结符表达式:文法中的每条规则对应于一个非终结表达式。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。Context环境角色:包含解释器之外的一些全局信息。客户角色:构建(或者被给定)表示该文法定义的语言中的一个特定的句子的抽象语法树;调用解释操作解释器是一个比较少用的模式,以下为其通用源码,可以作为参考。抽象表达式通常只有一个方法,如下所示。93第93页,共140页,2023年,2月20日,星期日行为模式Interpreter(解释器)效果通过对文法规则类的继承和扩展可以方便地改变和扩展文法。语法树上各节点类的实现大体相似,易于实现文法。复杂的文法将难以维护。可以方便地增加新的解释表达式的方式。实现抽象语法树的创建。定义解释操作。可以使用Flyweight模式共享终结符。94第94页,共140页,2023年,2月20日,星期日行为模式Iterator(迭代器)对象行为模式意图提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。适用性访问一个聚合对象的内容而无需暴露它的内部表示。支持对聚合对象的多个和多种遍历。为遍历不同的聚合结构提供一个统一的接口。95第95页,共140页,2023年,2月20日,星期日行为模式迭代这个名词对于熟悉Java的人来说绝对不陌生。我们常常使用JDK提供的迭代接口进行javacollection的遍历:Iterator

it

=

list.iterator();while(it.hasNext()){//using

“it.next();”do

some

businesss

logic}而这就是关于迭代器模式应用很好的例子。96第96页,共140页,2023年,2月20日,星期日行为模式Iterator(迭代器)97第97页,共140页,2023年,2月20日,星期日行为模式角色组成:迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。具体迭代器角色(ConcreteIterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。具体容器角色(ConcreteContainer):具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该容器的结构相关。98第98页,共140页,2023年,2月20日,星期日行为模式Iterator(迭代器)效果支持以不同方式遍历一个聚合。简化了聚合的接口,聚合不必再提供用于遍历的接口。在同一个聚合上可以有多个遍历。实现谁来控制迭代谁来提供遍历算法迭代器的健壮程度附加的迭代器操作多态迭代器的管理(堆中分配的迭代器的撤销)迭代器的特权访问复合对象上的迭代器空迭代器99第99页,共140页,2023年,2月20日,星期日行为模式Mediator(中介者)对象行为模式意图用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。适用性100第100页,共140页,2023年,2月20日,星期日行为模式Mediator(中介者)对象行为模式意图适用性一组对象以定义良好但是复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解。一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。想定制一个分布在多个类中的行为,而又不想生成太多的子类。101第101页,共140页,2023年,2月20日,星期日行为模式Mediator(中介者)102第102页,共140页,2023年,2月20日,星期日行为模式角色:抽象中介者(Mediator)角色:抽象中介者角色定义统一的接口用于各同事角色之间的通信。具体中介者(ConcreteMediator)角色:具体中介者角色通过协调各同事角色实现协作行为。为此它要知道并引用各个同事角色。同事(Colleague)角色:每一个同事角色都知道对应的具体中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。103第103页,共140页,2023年,2月20日,星期日行为模式104第104页,共140页,2023年,2月20日,星期日行为模式Mediator(中介者)105第105页,共140页,2023年,2月20日,星期日行为模式Mediator(中介者)效果减少了子类的生成,要改变行为只须生成Mediator的子类。将各Colleague解耦,有利于各Colleague间的松耦合。用一对多交互代替多对多交互,简化的交互协议。将对象间的协作关系抽象并封装,使交互关系更清楚。控制集中化可能导致Mediator的复杂性过高,难以维护。实现仅有一个Mediator时,可忽略抽象Mediator类。Colleague与Mediator间通信的实现。106第106页,共140页,2023年,2月20日,星期日行为模式Memento(备忘录)对象行为模式意图在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。适用性必须保存一个对象在某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。107第107页,共140页,2023年,2月20日,星期日行为模式Memento(备忘录)108第108页,共140页,2023年,2月20日,星期日行为模式角色:备忘录(Memento)角色:备忘录角色存储“备忘发起角色”的内部状态。“备忘发起角色”根据需要决定备忘录角色存储“备忘发起角色”的哪些内部状态。为了防止“备忘发起角色”以外的其他对象访问备忘录。备忘录实际上有两个接口,“备忘录管理者角色”只能看到备忘录提供的窄接口——对于备忘录角色中存放的属性是不可见的。“备忘发起角色”则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。109第109页,共140页,2023年,2月20日,星期日行为模式备忘录发起(Originator)角色:“备忘发起角色”创建一个备忘录,用以记录当前时刻它的内部状态。在需要时使用备忘录恢复内部状态。备忘录管理者(Caretaker)角色:负责保存好备忘录。不能对备忘录的内容进行操作或检查。110第110页,共140页,2023年,2月20日,星期日行为模式Memento(备忘录)效果保持了封装的边界。将状态交给Client去管理,简化了Originator。Memento的实现代价可能很高。需要对窄接口和宽接口的支持。维护Memento的潜在代价。实现窄接口和宽接口的实现。在Memento创建和撤销顺序可预测时,存储增量式改变。111第111页,共140页,2023年,2月20日,星期日行为模式Observer(观察者)对象行为模式意图定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。适用性112第112页,共140页,2023年,2月20日,星期日行为模式Observer(观察者)对象行为模式意图适用性当一个抽象模型有两个方面,其中一个方面依赖于另一方面,将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,不希望这些对象是紧密耦合的。113第113页,共140页,2023年,2月20日,星期日行为模式观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听(Source/Listener)模式或从属者(Dependents)模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。114第114页,共140页,2023年,2月20日,星期日行为模式一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其它的对象做出相应的改变。做到这一点的设计方案有很多,但是为了使系统能够易于复用,应该选择低耦合度的设计方案。减少对象之间的耦合有利于系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维持行动的协调一致,保证高度的协作(Collaboration)。观察者模式是满足这一要求的各种设计方案中最重要的一种。115第115页,共140页,2023年,2月20日,星期日行为模式Observer(观察者)116第116页,共140页,2023年,2月20日,星期日行为模式角色:抽象主题(Subject)角色:主题角色把所有对观察考对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,主题角色又叫做抽象被观察者(Observable)角色,一般用一个抽象类或者一个接口实现。抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口叫做更新接口。抽象观察者角色一般用一个抽象类或者一个接口实现。在这个示意性的实现中,更新接口只包含一个方法(即Update()方法),这个方法叫做更新方法。117第117页,共140页,2023年,2月20日,星期日行为模式具体主题(ConcreteSubject)角色:将有关状态存入具体现察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者角色(ConcreteObservable)。具体主题角色通常用一个具体子类实现。具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体现察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体现察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用一个具体子类实现。118第118页,共140页,2023年,2月20日,星期日行为模式Observer(观察者)效果目标与观察者之间的耦合是抽象和最小的。支持广播通信,对通知的响应取决于观察者。可能引起意外的更新。实现创建目标与观察者之间的映射。观察多个目标时,应修改Update使观察者知道发出通知的目标。Notify的触发。删除一个目标时,应通知观察者,避免悬挂引用。发出通知前确保目标状态的稳定。避免特定于观察者的更新协议——推/拉模型。可以显式地指定观察者感兴趣的改变。封装复杂的更新语义。119第119页,共140页,2023年,2月20日,星期日行为模式State(状态)对象行为模式意图允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。适用性120第120页,共140页,2023年,2月20日,星期日行为模式State(状态)对象行为模式意图适用性一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。121第121页,共140页,2023年,2月20日,星期日行为模式State(状态)122第122页,共140页,2023年,2月20日,星期日行为模式角色:使用环境(Context)角色:客户程序是通过它来满足自己的需求。它定义了客户程序需要的接口;并且维护一个具体状态角色的实例,这个实例来决定当前的状态状态(State)角色:定义一个接口以封装与使用环境角色的一个特定状态相关的行为。具体状态(ConcreteState)角色:实现状态角色定义的接口。123第123页,共140页,2023年,2月20日,星期日行为模式State(状态)124第124页,共140页,2023年,2月20日,星期日行为模式State(状态)效果将与特定状态相关的行为局部化,将不同状态的行为分割开来。使得状态转换显式化。State对象可以被共享。125第125页,共140页,2023年,2月20日,星期日行为模式Strategy(策略)对象行为模式意图定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。适用性126第126页,共140页,2023年,2月20日,星期日行为模式Strategy(策略)对象行为模式意图适用性许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。需要使用一个算法的不同变体。算法使用客户不应该知道的数据,可使用策略模式以避免暴露复杂的、与算法相关的数据结构。一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。127第127页,共140页,2023年,2月20日,星期日行为模式策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。假设现在要设计一个贩卖各类书籍的电子商务网站的购物车(ShoppingCat)系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论