宋航-设计模式.ppt

上传人:qwe****56 文档编号:69531489 上传时间:2023-01-06 格式:PPT 页数:154 大小:1.48MB
返回 下载 相关 举报
宋航-设计模式.ppt_第1页
第1页 / 共154页
宋航-设计模式.ppt_第2页
第2页 / 共154页
点击查看更多>>
资源描述

《宋航-设计模式.ppt》由会员分享,可在线阅读,更多相关《宋航-设计模式.ppt(154页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、设设计计模模式式主主讲:宋讲:宋航航设计模式设计模式l程序设计是思维具体化的一种方式,是思考如何解决问题的过程,设计模式是在解决问题的过程中,一些良好思路的经验集成,最早讲设计模式,人们总会提到 Gof的著作的著作,它最早将经典的 23 种模式集合在一起说明,对后期学习程序设计,尤其是对从事对象导向程序设计的人们起了莫大的影响。l后来设计模式一词被广泛的应用到各种经验集成,甚至还有反模式(AntiPattern),反模式教导您如何避开一些常犯且似是而非的程序设计思维。开闭原则开闭原则l“开闭”原则讲的是一个软件实体应当对扩展开放,对修改关闭。这个原则说的是,在设计一个模块的时候,应当使这个模块

2、可以在不被修改的前提不被扩展。换言之,应当可以在不必修改源代码的情况下改受这个模块的行为。l通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变化 中的软件系统有一定的适应性和灵活件。已有的软件模块,特别是最重要的抽象层模块不能再修改,这就使变化小的软件 系统有一定的稳定性和延续性。l解决问题的关键在于抽象化。在像Java语言这样的而向对象的编程语言里面,可以 给系统定义出一个一劳永逸、不再更改的抽象设计,此设计允许有无穷无尽的行为在实现.里氏代换原则里氏代换原则l里氏代换原则的严格表达是:一个软件实体如果使用的是一个基类的话,那么一定适用于其子类,而且它 根本不能察觉出基类对

3、象和子类对象的区别。l里氏代换原则是继承复用的基石。只有当衍生类可以替换掉基类,软件单位的功能不会受到影响时,基类才能真正被复用,而衍生类也才能够在基类的基础上增加新的行为。依赖倒转原则依赖倒转原则l在面向对象的系统里面,两个类之间可以发生三种不同的耦合关系:l零耦合关系:如果两个类没有耦合关系,就称之为零耦合。l具体耦合关系:具体耦合发生在两个具体的(可实例化 的)类之间,经出一个类对另外一个具体类的直接引用造成。l抽象耦合关系:抽象耦合关系发生在一个具体类和一个抽象类之间,使两个必须发生关系的类之间存有最大的灵活性。l简单地说,依赖倒转原则要求客户端依赖于抽象耦合接口隔离原则接口隔离原则l

4、一个接口对应一个角色,而不是多个角色。l定制服务也一个重要的设计原则。它的意思是说,如果客户端仅仅需要某一些方法的话,那么就应当向客户端提供这些方法,而不要提供不需 要的方法。迪米特原则迪米特原则l在软件系统中,一个模块设计得好不好的标志,就是该模块在多大的程度上将自己的内部数据和其他与实现有关的细节隐藏起来。这一概念就是“信息的隐藏”,或者叫做“封装”,也就是大家熟悉的软件设计的基本教义之一。l信息的隐藏非常重要的原因在于,它可以使各个子系统之间脱耦。这种脱耦化可以有效地加快系统的开 发过程,因为可以独立地同时开发各个模块。它可以使维护过程变得容易,因为所有的模块都容易读懂,特别是不必担心对

5、其他模块的影响。l 一旦确认某一个模块是性能的障碍时,设计人员可以到对这个模块本身进行优化,而不必担心影响到其他的模块。信息的隐藏可以促进软件的复用。一个系统的规模越大,信息的隐藏就越是重 要,而信息隐藏的威力也就越明显。SimpleFactory模式(又称模式(又称StaticFactory模式)模式)l假设有一个八音盒工厂,购买八音盒的客人不用知道八音盒是如何制作的,他只要知道如何播放八音盒就可以了,以 UML 类别图来表示以上的概念:例子例子lpublic interface IMusicBox public void play();lpublic class PianoBox impl

6、ements IMusicBox public void play()System.out.println(拨放钢琴音乐:);lpublic class ViolinBox implements IMusicBox public void play()System.out.println(拨放小提琴音乐_);例子例子lpublic class MusicBoxFactory public static IMusicBox createMusicBox(String name)throws InstantiationException,IllegalAccessException,ClassNo

7、tFoundException /这边使用的是Java的Reflection机制来产生实例 /不过客户端不用管啦 /以后就算改变了程序,客户端程序是不用更改的 return(IMusicBox)Class.forName(name).newInstance();例子例子lpublic class MusicBoxDemo public static void main(String args)throws Exception playMusicBox(MusicBoxFactory.createMusicBox(PianoBox);playMusicBox(MusicBoxFactory.cr

8、eateMusicBox(ViolinBox);public static void playMusicBox(IMusicBox musicBox)musicBox.play();l由于客户端只依赖于IMusicBox接口,所以即使您日后改变了createMusicBox()中的实作方式,对客户端是一点影响也没有的。SimpleFactory的类别结构的类别结构抽象工厂抽象工厂产品族产品族采用抽象工厂模式设计出的系统类图采用抽象工厂模式设计出的系统类图在什么情形下应当使用抽象工厂模式在什么情形下应当使用抽象工厂模式l(1)一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节。这对于所有

9、形态的工厂模式都是重要的;l(2)这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品;(上面这一条叫做抽象工厂模式的原始用意。)l(3)同属于同一个产品族的产品是在一起使用的,这一约束必须要在系统的设计中体现出来;l(4)系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。类图类图系统的设计图系统的设计图抽象工厂模式的另一个例子抽象工厂模式的另一个例子l这个例子描述微型计算机配件的生产。这个系统所需要的产品族有两个,一个系列是PC,或称IBM 及IBM 克隆机系列;另一个系列是MAC,或称MacIntosh 系列。产品等级结构也有两个,一个是RAM,另一个

10、是CPU。系统的设计图系统的设计图“开开-闭闭”原则原则l“开-闭”原则要求一个软件系统可以在不修改原有代码的情况下,通过扩展达到增强其功能的目的。对于一个涉及到多个产品等级结构和多个产品族的系统,其功能的增强不外乎两个方面:l增加新的产品族;l增加新的产品等级结构。l那么抽象工厂模式是怎样支持这两方面功能增强的呢?增加新的产品族增加新的产品族l在产品等级结构的数目不变的情况下,增加新的产品族,就意味着在每一个产品等级结构中增加一个(或者多个)新的具体(或者抽象和具体)产品角色。l由于工厂等级结构是与产品等级结构平行的登记机构,因此,当产品等级结构有所调整时,需要将工厂等级结构做相应的调整。现

11、在产品等级结构中出现了新的元素,因此,需要向工厂等级结构中加入相应的新元素就可以了。l换言之,设计师只需要向系统中加入新的具体工厂类就可以了,没有必要修改已有的工厂角色或者产品角色。构造模式构造模式l您想要建立一个迷宫产生程序,迷宫使用二维数组来定义,0表示道路,1表示墙,2表示宝物,根据所定义的二维迷宫数组,您想要程序自动产生各种不同材质的迷宫,例如砖墙迷宫,钻石迷宫等等。l您可以在程序中定义两个角色,一个是指导迷宫建立的Director角色,一个是按照指导者指示建立迷宫的Builder角色,Director根据定义的迷宫数组来指导Builder,只要更换Builder,就可以完成不同材质的

12、迷宫。构造模式构造模式lpublicclassMazeDirectorprivateintmaze;privateIMazeBuildermazeBuilder;publicvoidsetMaze(intmaze)this.maze=maze;publicvoidsetMazeBuilder(IMazeBuildermazeBuilder)this.mazeBuilder=mazeBuilder;publicvoidbuildMaze()for(inti=0;imaze.length;i+)for(intj=0;jmazei.length;j+)/由于由于mazeBuilder是是IMazeB

13、uilder型态型态/所以无论所以无论Builder实例为何,这边的程序都无需变动实例为何,这边的程序都无需变动switch(mazeij)case0:mazeBuilder.createRoadBlock();break;case1:mazeBuilder.createWallBlock();break;case2:mazeBuilder.createTreasureBlock();break;default:System.out.println(undefined);mazeBuilder.nextRow();lpublicinterfaceIMazeBuilderpublicvoidcr

14、eateRoadBlock();publicvoidcreateWallBlock();publicvoidcreateTreasureBlock();publicvoidnextRow();lpublicclassSolidMazeBuilderimplementsIMazeBuilderpublicvoidcreateWallBlock()System.out.print();publicvoidcreateRoadBlock()System.out.print();publicvoidcreateTreasureBlock()System.out.print($);publicvoidn

15、extRow()System.out.println();lpublic class DiamondMazeBuilder implements IMazeBuilder public void createWallBlock()System.out.print();public void createRoadBlock()System.out.print();public void createTreasureBlock()System.out.print(*);public void nextRow()System.out.println();lpublicclassMainpublics

16、taticvoidmain(Stringargs)intmaze=1,1,1,1,1,1,1,1,0,0,0,0,2,1,1,0,1,0,1,0,1,1,0,2,1,0,1,1,1,1,0,1,0,1,1,1,0,0,2,0,0,1,1,1,1,1,1,1,1;MazeDirectormazeDirector=newMazeDirector();mazeDirector.setMaze(maze);System.out.println(BuildSolidMaze.);mazeDirector.setMazeBuilder(newSolidMazeBuilder();mazeDirector.

17、buildMaze();System.out.println(BuildDiamondMaze.);mazeDirector.setMazeBuilder(newDiamondMazeBuilder();mazeDirector.buildMaze();构造模式构造模式l简单来说,建筑者模式适用的场合,在于使得您可以依赖抽象的建筑蓝图,而实际建造时可以使用不同的实例,这是其之所以命为Builder的原因。FactoryMethod模式模式lFactory Method模式在一个抽象类中留下某个创建组件的抽象方法没有实作,其它与组件操作相关联的方法都先依赖于组件所定义的接口,而不是依赖于组件的实

18、现,当您的成品中有一个或多个组件无法确定时,您先确定与这些组件的操作接口,然后用组件的抽象操作接口先完成其它的工作,组件的实现则推迟至实现组件接口的子类完成,一旦组件加入,即可完成您的成品。l假设您要完成一个文件编辑器,您希望这个编辑器可以适用于所有类型的档案编辑,例如RTF、DOC、TXT等等,尽管这些文件有着不同的格式,您先确定的是这些文件必然具备的一些操作接口,例如储存、开启、关闭等等,您用一个IDocument类型来进行操作,这么一来这个框架就无需考虑实际的储存、开启等细节是如何进行的。FactoryMethod模式模式FactoryMethod模式模式lpublicabstractc

19、lassAbstractEditorprivateIDocumentdocument;publicabstractIDocumentcreateDocument();publicvoidnewDocument()document=createDocument();document.open();publicvoidsaveDocument()if(document!=null)document.save();publicvoidcloseDocument()if(document!=null)document.close();FactoryMethod模式模式lpublic interface

20、 IDocument public void open();public void save();public void close();lpublic class RTFEditor extends AbstractEditor public IDocument createDocument()return new RTFDocument();FactoryMethod模式模式lpublicclassRTFDocumentimplementsIDocumentpublicRTFDocument()System.out.println(建立建立RTF文件文件);publicvoidopen()

21、System.out.println(开启文件开启文件);publicvoidsave()System.out.println(储存文件储存文件);publicvoidclose()System.out.println(关闭文件关闭文件);FactoryMethodlFactory Method中的AbstractOperator中拥有一个抽象的factoryMethod()方法,它负责生成一个IProduct类型的对象,由于目前还不知道将如何实现这个类型,所以将之推迟至子类别中实现,在AbstractOperator中先实现IProduct操作接口沟通的部份,只要接口统一了,利用多型操作即可

22、完成各种不同的IProduct类型之对象操作。Prototype模式模式l您从图书馆的期刊从发现了几篇您感兴趣的文章,由于这是图书馆的书,您不可以直接在书中作记号或写字,所以您将当中您所感兴趣的几个主题影印出来,这下子您就可在影印的文章上画记重点。lPrototype模式的作用有些类似上面的描述,您在父类别中定义一个clone()方法,而在子类别中重新定义它,当客户端对于所产生的对象有兴趣并想加以利用,而您又不想破坏原来的对象,您可以产生一个对象的复本给它。Prototype模式模式lPrototype具有展示的意味,就像是展览会上的原型车款,当您对某个车款感兴趣时,您可以购买相同款示的车,而

23、不是车展上的车。l在软件设计上的例子会更清楚的说明为何要进行对象复制,假设您要设计一个室内设计软件,软件中有一个展示家具的工具列,您只要点选工具列就可以产生一个家具复本,例如一张椅子或桌子,您可以拖曳这个复制的对象至设计图中,随时改变它的位置、颜色等等,当您改变设计图中的对象时,工具列上的原型工具列是不会跟着一起改变的,这个道理是无需解释的。Prototype模式模式Prototype模式模式lPrototype模式的重点在于clone(),它负责复制对象本身并传回,但这个clone()本身在实作上存在一些困难,尤其是当对象本身又继承另一个对象时,如何确保复制的对象完整无误,在不同的程序语言中

24、有不同的作法。在Java中的作法是透过实作一个Cloneable接口,它只是一个声明的界面,并无规定任何实作的方法,您的目的是改写Object的clone()方法,使其具备有复制对象的功能。Prototype模式模式lpublic abstract class AbstractFurniture implements Cloneable public abstract void draw();/在Design Pattern上,以下的clone是抽象未实作的 /实际上在Java中class都继承自Object /所以在这边我们直接重新定义clone()/这是为了符合Java现行的clone机制

25、 protected Object clone()throws CloneNotSupportedException return super.clone();limportjava.awt.*;publicclassCircleTableextendsAbstractFurnitureprotectedPointcenter;publicvoidsetCenter(Pointcenter)this.center=center;protectedObjectclone()throwsCloneNotSupportedExceptionObjecto=super.clone();if(this.

26、center!=null)(CircleTable)o).center=(Point)center.clone();returno;publicvoiddraw()System.out.println(t圆桌圆桌t中心:中心:(+center.getX()+,+center.getY()+);limportjava.awt.*;publicclassSquareTableextendsAbstractFurnitureprotectedRectanglerectangle;publicvoidsetRectangle(Rectanglerectangle)this.rectangle=rect

27、angle;protectedObjectclone()throwsCloneNotSupportedExceptionObjecto=super.clone();if(this.rectangle!=null)(SquareTable)o).rectangle=(Rectangle)rectangle.clone();returno;publicvoiddraw()System.out.print(t方桌方桌t位置:位置:(+rectangle.getX()+,+rectangle.getY()+);System.out.println(/宽高:宽高:(+rectangle.getWidth

28、()+,+rectangle.getHeight()+);limportjava.util.*;publicclassHouseprivateVectorvector;publicHouse()vector=newVector();publicvoidaddFurniture(AbstractFurniturefurniture)vector.addElement(furniture);System.out.println(现有家具现有家具.);Enumerationenumeration=vector.elements();while(enumeration.hasMoreElements(

29、)AbstractFurnituref=(AbstractFurniture)enumeration.nextElement();f.draw();System.out.println();limportjava.awt.*;publicclassApplicationprivateAbstractFurniturecircleTablePrototype;publicvoidsetCircleTablePrototype(AbstractFurniturecircleTablePrototype)this.circleTablePrototype=circleTablePrototype;p

30、ublicvoidrunAppExample()throwsExceptionHousehouse=newHouse();CircleTablecircleTable=null;/从工具列选择一个家具加入房子中从工具列选择一个家具加入房子中circleTable=(CircleTable)circleTablePrototype.clone();circleTable.setCenter(newPoint(10,10);house.addFurniture(circleTable);/从工具列选择一个家具加入房子中从工具列选择一个家具加入房子中circleTable=(CircleTable)

31、circleTablePrototype.clone();circleTable.setCenter(newPoint(20,30);house.addFurniture(circleTable);publicstaticvoidmain(Stringargs)throwsExceptionApplicationapplication=newApplication();application.setCircleTablePrototype(newCircleTable();application.runAppExample();PrototypelJava中的clone()方法是继承自Obje

32、ct,AbstractFurniture的子类别则override这个clone()方法,以复制其本身并传回。单例(单例(Singleton)模式)模式l单例单例显然单例模式的要点有三个;l一是某各类只能有一个实例;l二是它必须自行创建这个事例;l三是它必须自行向整个系统提供这个实例。在下面的对象图中,有一个“单例对象”,而“客户甲”、“客户乙”和“客户丙”是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。资源管理资源管理l在计算机系统中,需要管理的资源包括软件外部资源,譬如每台计算机可以有若干个打印机,但只能有

33、一个Printer Spooler,以避免两个打印作业同时输出到打印机中。l每台计算机可以有若干传真卡,但是只应该有一个软件负责管理传真卡,以避免出现两份传真作业同时传到传真卡中的情况。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。l这些资源管理器构件必须只有一个实例,这是其一;它们必须自行初始化,这是其二;允许整个系统访问自己这是其三。因此,它们都满足单例模式的条件,是单例模式的应用。单例模式的结构单例模式的结构l单例模式有以下的特点:l单例类只可有一个实例。l单例类必须自己创建自己这惟一的实例。l单例类必须给所有其他对象提供这一实例。

34、l虽然单例模式中的单例类被限定只能有一个实例,但是单例模式和单例类可以很容易被推广到任意且有限多个实例的情况,这时候称它为多例模式(Multiton Pattern)和多例类.饿汉式单例类饿汉式单例类public class EagerSingletonprivate static final EagerSingleton m_instance=new EagerSingleton();private EagerSingleton()public static EagerSingleton getInstance()return m_instance;l在这个类被加载时,静态变量m_insta

35、nce 会被初始化,此时类的私有构造子会被调用。这时候,单例类的惟一实例就被创建出来了。lJava 语言中单例类的一个最重要的特点是类的构造子是私有的,从而避免外界利用构造子直接创建出任意多的实例。值得指出的是,由于构造子是私有的,因此,此类不能被继承。懒汉式单例类懒汉式单例类public class LazySingleton private static LazySingleton m_instance=null;private LazySingleton()synchronized public static LazySingleton getInstance()if(m_instanc

36、e=null)m_instance=new LazySingleton();return m_instance;l读者可能会注意到,在上面给出懒汉式单例类实现里对静态工厂方法使用了同步化,以处理多线程环境。使用单例模式的条件使用单例模式的条件l使用单例模式有一个很重要的必要条件:l在一个系统要求一个类只有一个实例时才应当使用单例模式。l反过来说,如果一个类可以有几个实例共存,那么就没有必要使用单例类。错误例子一错误例子一l问:我的一个系统需要一些“全程”变量。学习了单例模式后,我发现可以使用一个单例类盛放所有的“全程”变量。请问这样做对吗?l答:这样做是违背单例模式的用意的。单例模式只应当在有

37、真正的“单一实例”的需求时才可使用。一个设计得当的系统不应当有所谓的“全程”变量,这些变量应当放到它们所描述的实体所对应的类中去。将这些变量从它们所描述的实体类中抽出来,放到一个不相干的单例类中去,会使得这些变量产生错误的依赖关系和耦合关系。有状态的单例类有状态的单例类l一个单例类可以是有状态的(stateful),一个有状态的单例对象一般也是可变(mutable)单例对象。l有状态的可变的单例对象常常当做状态库(repositary)使用。比如一个单例对象可以持有一个int 类型的属性,用来给一个系统提供一个数值惟一的序列号码,作为某个贩卖系统的账单号码。l当然,一个单例类可以持有一个聚集,

38、从而允许存储多个状态。没有状态的单例类没有状态的单例类l另一方面,单例类也可以是没有状态的(stateless),仅用做提供工具性函数的对象。l既然是为了提供工具性函数,也就没有必要创建多个实例,因此使用单例模式很合适。一个没有状态的单例类也就是不变(Immutable)单例类.Java的的Runtime对象对象l在Java 语言内部,java.lang.Runtime 对象就是一个使用单例模式的例子。在每一个Java应用程序里面,都有惟一的一个Runtime 对象。通过这个Runtime 对象,应用程序可以与其运行环境发生相互作用。lRuntime 类提供一个静态工厂方法getRuntime

39、():,通过调用此方法,可以获得Runtime 类惟一的一个实例.Runtime 对象通常的用途包括:执行外部命令;返回现有内存即全部内存;运行垃圾收集器;加载动态库等。import java.io.*;public class CmdTest public static void main(String args)throws IOException Process proc=Runtime.getRuntime().exec(notepad.exe);什么是不完全的单例类什么是不完全的单例类lpackage com.javapatterns.singleton.demos;lpublic

40、class LazySingleton lpublic LazySingleton()l造成这种情况出现的原因有以下几种可能:l(1)初学者的错误。许多初学者没有认识到单例类的构造子不能是公开的,因此犯下这个错误。有些初学Java 语言的学员甚至不知道一个Java 类的构造子可以不是公开的。l(2)当初出于考虑不周,将一个类设计成为单例类,后来发现此类应当有多于一个的实例。为了弥补错误,干脆将构造子改为公开的l(3)设计师的Java 知识很好,而且也知道单例模式的正确使用方法,但是还是有意使用这种不完全的单例模式,因为他意在使用一种“改良”的单例模式。ObjectAdapterl您的计算机是个

41、旧计算机,新的鼠标都在使用USB接口了,而您的计算机上并没有USB,而只有一个PS2接口,这时您可以使用一个USB转PS2的接头作为转换,这样您的计算机就可以使用新鼠标了(当然您也可以使用USB扩充卡,意思是相同的)。l类似的概念,有时候您想在原来的程序中加入一个外部组件,例如一个类别,但是这个类别与您目前所设计的程序在接口上并不一致,为了让这个外部类与原程序的接口一致,您必须使用一个类别作为中介来配接它们,这时您可以采用Adapter模式。l举个例子来说,在Java 1.0中有个Enumeration,您在这个版本发行之后,使用它来设计了一个MessageApplication Object

42、Adapterlimport java.util.*;public class MessageApplication public void showAllMessage(Enumeration enum)Object msg;while(enum.hasMoreElements()msg=enum.nextElement();System.out.println(msg);ObjectAdapterlimportjava.util.*;publicclassMessageClientprivateMessageApplicationmsgApp;publicvoidrun()Vectorve

43、ctor=newVector();for(inti=0;i10;i+)vector.addElement(物件物件+i);msgApp=newMessageApplication();msgApp.showAllMessage(vector.elements();publicstaticvoidmain(Stringargs)MessageClientmsgClient=newMessageClient();msgClient.run();ObjectAdapterlimportjava.util.*;publicclassIteratorAdapterimplementsEnumeratio

44、nprivateIteratoriterator;IteratorAdapter(Iteratoriterator)this.iterator=iterator;/转接界面转接界面publicbooleanhasMoreElements()returniterator.hasNext();publicObjectnextElement()throwsNoSuchElementExceptionreturniterator.next();limportjava.util.*;publicclassMessageClient/WecouldstilluseMessageApplicationpri

45、vateEnumerationiteratorAdapter;publicvoidrun()ListarrayList=newArrayList();for(inti=0;i10;i+)arrayList.add(物件物件+i);iteratorAdapter=newIteratorAdapter(arrayList.iterator();/WecouldstilluseMessageApplicationMessageApplicationmsgApp=newMessageApplication();msgApp.showAllMessage(iteratorAdapter);publics

46、taticvoidmain(Stringargs)MessageClientmsgClient=newMessageClient();msgClient.run();ObjectAdapterClassAdapterlAdapter模式的另一种作法是Class Adapter模式,在这个模式下,Adapter直接继承Adaptee(要引进的新类别),以拥有当中的成员及方法,在C+中的话可以这么作:ClassAdapterl如果有SomeClass类别与OtherClass类别,您想要SomeAndOther类别可以同时拥有SomeClass类别与 OtherClass类别中已定义好的操作,并可

47、以进行多型操作,在C+中可以用多重继承来达到,但在Java中显然的无法使用多重继承,怎么办?您可以在设计上先绕个弯,先使用两个接口分别定义好SomeClass与OtherClass两个类别的公开方法,例如:lpublicinterfaceISomepublicvoiddoSome();publicinterfaceIOtherpublicvoiddoOther();ClassAdapterl接着让SomeClass与OtherClass分别实作两个接口:lpublicclassSomeClassimplementsISomepublicvoiddoSome().lpublicclassOthe

48、rClassimplementsIOtherpublicvoiddoOther().ClassAdapterlSomeAndOther如何同时拥有两个SomeClass与OtherClass类别已定义好的操作?并可以多型操作?SomeAndOther可以继承其中之一,并拥有其中之一,例如:lpublicclassSomeAndOtherextendsSomeClassimplementsIOtherprivateIOtherother=newOtherClass();publicvoiddoOther()other.doOther();l虽不满意,但至少解决了目前的问题,当然这边只是其中一例,

49、毕竟C+是C+,Java是Java,两者语法并不是一对一的关系,视实际需求还可以变化一下。设计模式之BridgelBridge定义:将抽象和行为划分开来,各自独立,但能动态的结合.l为什么使用?通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以下两种:1.这多个具体实现之间恰好是并列的,2.实际应用上,常常有可能在这多个concrete class之间有概念上重叠.那么需要我们把抽象共同部分和行为共同部分各自独立开来,原来是准备放在一个接口里,现在需要设计两个接口,分别放置抽象和行为.Bridge的意义的意义l在这里,脱耦是指将抽

50、象化和实现化之间的耦合解脱开,或说将它们之间的强关联改换成弱关联。l所谓强关联,就是在编译时期已经确定的,无法在运行时期动态改变的关联;l所谓弱关联,就是可以动态地确定并且可以在运行时期动态地改变的关联。l显然继承关系是强关联,而聚合关系是弱关联。将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联换成为弱关 联。因此,桥梁模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合聚合关系而不是继承关系,从而使两者可以相对独立地变化。问题问题l空中巴士、波音和麦道都是飞机制造商,它们都生产载客飞机和载货飞机:现在需要设计一个系 统,描述这些飞机制造商以及它们所制造的飞机种类。设

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > 财经金融

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com