您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 设计模式课程设计报告
课程设计报告一、问题要求及任务描述设计模式课程作业要求独立制作一个软件,功能是实现23种模式的定义、优缺点以及显示示例代码。(一)、题目要求设计软件,将23种设计模式结合,要能够显示每种模式的定义、优缺点以及举例说明例子,加上简单的代码说明。(二)、主要任务主要是选择一种工具,实现显示的功能,整理各种模式的定义,概念、使用情况、以及选择模式实例,代码实现;(三)、典型实例实现(任选三个分属于不同设计模式的实例)1、单例模式定义与结构单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。单例模式的要点显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。在下面的对象图中,有一个单例对象,而客户甲、客户乙和客户丙是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。静态变量(这是c/c++的叫法,其他语言或有不同)是实现单例模式的要素。单例模式的2种方式:饿汉式,懒汉式单例模式属于对象创建型模式,其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点。对一些类来说,只有一个实例是很重要的,虽然系统中可以有许多打印机,但却只应该有一个打印机假脱机,只应该有一个文件系统和一个窗口管理器,一个数字滤波器只能有一个A/D转换器,一个会计系统只能专用于一个公司。怎样才能保证一个类只有一个实例并且这个实例易于被访问,一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象,一个更好的方法是让类自身负责保存他的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法,这就是Singleton模式。UML图:饿汉式,懒汉式classSingleton{privatestaticSingletoninstance=newSingleton();privateSingleton(){}staticSingletongetInstance(){returninstance;}}懒汉式classSingleton{privatestaticSingletoninstance=null;privateSingleton(){}staticSingletongetInstance(){if(instance==null)instance=newSingleton();returninstance;}}一个产生随机数的例子,整个应用程序中只需要一个类的实例来产生随机数,客户端程序从类中获取这个实例,调用这个实例的方法nextInt(),公用的方法访问需要进行同步,这是单例模式需要解决的同步问题。publicclassSingleton{privateSingleton(){generator=newRandom();}publicvoidsetSeed(intseed){generator.setSeed(seed);}publicintnextInt(){returngenerator.nextInt();}publicstaticsynchronizedSingletongetInstance(){if(instance==null){instance=newSingleton();}returninstance;}privateRandomgenerator;privatestaticSingletoninstance;}客户端调用的代码:packagesingleton;publicclassClient{publicstaticvoidmain(String[]args){Singletons1=Singleton.getInstance();System.out.println(s1.toString());for(inti=0;i10;i++){Singletons2=Singleton.getInstance();System.out.println(Therandomednumberis+s2.toString());}}}2、工厂方法模式定义与结构工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。适用情况第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。JavaCollection中的iterator()方法即属于这种情况。第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。优缺点首先,良好的封装性,代码结构清晰。一个对象创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,减少模块间的耦合。其次,工厂方法模式的扩展性非常优秀。在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,就可以完成“拥抱变化”。例如在我们的例子中,需要增加一个棕色人种,则只需要增加一个BrownHuman类,工厂类不用任何修改就可完成系统扩展。再次,屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不表,系统中的上层模块就不要发生变化,因为产品类的实例化工作是由工厂类负责,一个产品对象具体由哪一个产品生成是由工厂类决定的。在数据库开发中,大家应该能够深刻体会到工厂方法模式的好处:如果使用JDBC连接数据库,数据库从MySql切换到Oracle,需要改动地方就是切换一下驱动名称(前提条件是SQL语句是标准语句),其他的都不需要修改,这是工厂方法模式灵活性的一个直接案。最后,工厂方法模式是典型的解耦框架。高层模块值需要知道产品的抽象类,其他的实现类都不用关心,符合迪米特原则,我不需要的就不要去交流;也符合依赖倒转原则,只依赖产品类的抽象;当然也符合里氏替换原则,使用产品子类替换产品父类,没问题!UML图实例代码源代码1//产品Plant接口23publicinterfacePlant{}45//具体产品PlantA,PlantB67publicclassPlantAimplementsPlant{89publicPlantA(){1011System.out.println(createPlantA!);1213}1415publicvoiddoSomething(){1617System.out.println(PlantAdosomething...);1819}2021}2223publicclassPlantBimplementsPlant{2425publicPlantB(){2627System.out.println(createPlantB!);2829}3031publicvoiddoSomething(){3233System.out.println(PlantBdosomething...);3435}3637}3839//产品Fruit接口4041publicinterfaceFruit{}4243//具体产品FruitA,FruitB4445publicclassFruitAimplementsFruit{4647publicFruitA(){4849System.out.println(createFruitA!);5051}5253publicvoiddoSomething(){5455System.out.println(FruitAdosomething...);5657}5859}6061publicclassFruitBimplementsFruit{6263publicFruitB(){6465System.out.println(createFruitB!);6667}6869publicvoiddoSomething(){7071System.out.println(FruitBdosomething...);7273}7475}7677//抽象工厂方法7879publicinterfaceAbstractFactory{8081publicPlantcreatePlant();8283publicFruitcreateFruit();8485}8687//具体工厂方法8889publicclassFactoryAimplementsAbstractFactory{9091publicPlantcreatePlant(){9293returnnewPlantA();9495}9697publicFruitcreateFruit(){9899returnnewFruitA();100101}102103}104105publicclassFactoryBimplementsAbstractFactory{106107publicPlantcreatePlant(){108109returnnewPlantB();110111}112113publicFruitcreateFruit(){114115returnnewFruitB();116117}118119}3、备忘录模式定义与结构备忘录(Memento)模式又称标记(Token)模式。GOF给备忘录模式的定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。从定义可以看出备忘录模式是专门来存放对象历史状态的,这对于很好的实现undo、redo功能有很大的帮助。所以在命令模式中undo、redo功能可以配合备忘录模式来实现。适用情况使用了备忘录模式来实现保存对象的历史状态可以有效地保持封装边界。使用备忘录可以避免暴露一些只应由“备忘发起角色”管理却又必须存储在“备忘发起角色”之外的信息。把“备忘发起角色”内部信息对其他对象屏蔽起来,从而保持了封装边界。但是如果备份的“备忘发起角色”存在大量的信息或者创建、恢复操作非常频繁,则可能造成很大的开销。GOF在《设计模式》中总结了使用备忘录模式的前提:1)必须保存一个对象在某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。2)如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。优缺点优点:使用备忘录模式,可以避免暴露一些只应由源发器管理却又必须存储在源发器之外的信息,而且能够在对象需要时恢复到先前的状态。缺点:使用备忘录可能代价很高。如果源发器在生成备忘录时必须复制并存储大量的信息,或者客户非常频繁地创建备忘录和恢复源发器状态,可能会导致非常大的开销。UML图1)备忘录(Memento)角色:备忘录角色存储“备忘发起角色”的内部状态。“备忘发起角色”根据需要决定备忘录角色存储“备忘发起角色”的哪些内部状态。为了防止“备忘发起角色”以外的其他对象访问备忘录。备忘录实际上有两个接口,“备忘录管理者角色”只能
本文标题:设计模式课程设计报告
链接地址:https://www.777doc.com/doc-2066037 .html