宋航-设计模式.ppt
《宋航-设计模式.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.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 宋航 设计 模式
限制150内