Java设计模式.pdf

上传人:qwe****56 文档编号:69565839 上传时间:2023-01-07 格式:PDF 页数:58 大小:532.88KB
返回 下载 相关 举报
Java设计模式.pdf_第1页
第1页 / 共58页
Java设计模式.pdf_第2页
第2页 / 共58页
点击查看更多>>
资源描述

《Java设计模式.pdf》由会员分享,可在线阅读,更多相关《Java设计模式.pdf(58页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、设计模式 5.1 概述概述 一个围棋下得好的人知道,好的形对于围棋非常重要形是棋子在棋盘上的几何形状的抽象化 形就是模式(Pattern),也是人脑把握和认识外界的关键而人脑对处理模式的能力也非常高超 人 可以在几百张面孔中一下子辨认出所熟悉的脸来,就是一个例子 简而言之,在我们处理大量问题时,在很多不同的问题中重复出现的一种性质,它使得我们可以使用一 种方法来描述问题实质并用本质上相同,但细节永不会重复的方法去解决,这种性质就叫模式模式化过程是把问题抽象化,在忽略掉不重要的细节后,发现问题的一般性本值,并找到普遍使用的方法 去解决的过程 发现模式是与研究模式同时发生的 发现一个新的模式很不容

2、易 一个好的模式必须满足以下几点 1它可以解决问题模式不能仅仅反映问题而必须对问题提出解决方案 2它所提出解决方案是正确的而且不是很明显的 3它必须是涉及软件系统深层的结构的东西不能仅是对已有的模块的描述 4它必须满足人的审美简洁美观 换言之一个美妙的东西不一定就是模式但是一个模式必须是一个美妙的东西 ac 软件工程学的各个方面诸如开发组织软件处理项目配置管理等等都可以看到模式的影子但至今 得到了最好的研究的是设计模式和组织模式在软件编程中使用模式化方法,是在编程对象化之后才开始得到重视的 软件编程中模式化方法的研究,也是在九十年代才开始 在面向对象的编程中使用模式化方法研究的开创性著作,是

3、Design Patterns-Elements of Reusable Object-Oriented Software,E.Gamma,R.Helm,R.Johnson,and J.Vlissides,1995,Addison-Wesley.这四位作者通常被称为四人帮(Gang of Four,或 GoF)5.2 创立性模式创立性模式 创立性模式(Creational Patterns)是类在实例化时使用的模式当一些系统在创立对象时,需要动态地决定怎样创立对象,创立哪些对象创立性模式告诉我们怎样构造和包装这些动 态的决定 面向对象的设计的目的之一,就是把责任进行划分,以分派给不同的对象我们

4、推荐这种划分责任的作法,是因为它和封装(Encapsulation)和委托(Delegation)的精神是相符合的创立性模式把对象的创立过程封装起来,使得创立实例的责任与使用实例的责任分割开,并由专门的模块分管实例的创立,而系统在宏观上不再依赖于对象创立过程的细节 所有面向对象的语言都有固定的创立对象的办法Java 语言办法就是使用 new 操作符比如 StringBuffer s=new StringBuffer(1000);就创立了一个对象 s,其类型是 StringBuffer使用 new 操作符的短处是事先必须明确知道要实例化的类是什么,而且实例化的责任往往与使用实例的责任不加区分使用

5、创立性模式将类实例化,首先不必事先知道每次是要实例化哪一个类,其次把实例化的责任与使用实例的责任分割开来,可以 弥补直接使用 new 操作符的短处 而工厂模式就是专门负责将大量有共同接口的类实例化,而且不必事先知道每次是要实例化哪一个类的模式 创立性模式通常包括 以下的模式 1简单工厂模式 2抽象工厂类模式 3建设者模式 4原型模式 5单态模式 5.2.1 简单工厂模式 一个简单工厂模式根据提供给它的数据返回几个可能的类中一个类的实例通常返回实例所属的类都有一个公共的超类和一个公共的方法但是他们都执行一个不同的任务 再下图中,X 是一个超类类 XY 和 XZ 是 X 的子类Factory 是一

6、个类它根据传给它的参数决定返回那个子类在该类中我们设计一个方法 getClass传给它一个参数值”abc”它返回类 X 的某个实例对于给类 factory 的对象发送 getClass(“abc”)消息的程序员不关心getClass 返回哪个子类的实例因为这些在类和超类有相同的方法但是有不同的实现具体返回哪个类的对象由 getClass 方法内部来实现 Factory getClass(abc):X xz xy x 例如有一个描述你的后花园的系统,在你的后花园里有各种的花,但还没有水果你现在要往你的系统里引进一些新的类,用来描述下列的水果:葡萄 Grapes 草莓 Strawberry 苹果

7、Apple 花和水果最大的不同,就是水果最终是可以采摘食用的那么,很自然的作法就是建立一个各种水果 都适用的接口,这样一来这些水果类作为相似的数据类型就可以和你的系统的其余部分,如各种的花 有所不同,易于区分 图 5.1 Grape,Strawberry 和 Apple 是拥有共同接口 FruitIF 的类 package com.javapatterns.simplefactory;public interface FruitIF void grow();void harvest();void plant();String color=null;String name=null;代码清单 1

8、.接口 FruitIF 的源代码这个接口确定了水果类必备的方法:种植 plant(),生长grow(),以 及收获 harvest()package com.javapatterns.simplefactory;public class Apple implements FruitIF public void grow()log(Apple is growing.);public void harvest()log(Apple has been harvested.);public void plant()log(Apple has been planted.);public static v

9、oid log(String msg)System.out.println(msg);public int getTreeAge()return treeAge;public void setTreeAge(int treeAge)this.treeAge=treeAge;private int treeAge;代码清单 2.类 Apple 的源代码苹果是多年生木本植物,因此具备树龄 treeAge 性质 package com.javapatterns.simplefactory;public class Grape implements FruitIF public void grow()

10、log(Grape is growing.);public void harvest()log(Grape has been harvested.);public void plant()log(Grape has been planted.);public static void log(String msg)System.out.println(msg);public boolean getSeedful()return seedful;public void setSeedful(boolean seedful)this.seedful=seedful;private boolean s

11、eedful;代码清单 3.类 Grape 的源代码葡萄分为有籽与无籽两种,因此具有 seedful 性质 package com.javapatterns.simplefactory;public class Strawberry implements FruitIF public void grow()log(Strawberry is growing.);public void harvest()log(Strawberry has been harvested.);public void plant()log(Strawberry has been planted.);public s

12、tatic void log(String msg)System.out.println(msg);代码清单 4.类 Strawberry 的源代码 你作为小花果园的主人兼园丁,也是系统的一部分,自然要由一个合适的类来代表,这个类就是 FruitGardener 类这个类的结构请见下面的 UML 类图 图 2.FruitGardener 类图 FruitGardener 类会根据要求,创立出不同的水果类,比如苹果 Apple葡萄 Grape 或草莓Strawberry 实例 package com.javapatterns.simplefactory;public class FruitGar

13、dener public FruitIF factory(String which)throws BadFruitException if(which.equalsIgnoreCase(apple)return new Apple();else if(which.equalsIgnoreCase(strawberry)return new Strawberry();else if(which.equalsIgnoreCase(grape)return new Grape();else throw new BadFruitException(Bad fruit request);代码清单 5.F

14、ruitGardener 类的源代码 在使用时,只须调用 FruitGardener 的 factory()方法即可 FruitGardener gardener=new FruitGardener();gardener.factory(grape);gardener.factory(apple);gardener.factory(strawberry);总而言之,简单工厂模式就是由一个工厂类根据参数来决定创立出那一种产品类的实例下面的 UML 类图就精确定义了简单工厂模式的结构 图 4.简单工厂模式定义的类图 public class Creator public Product facto

15、ry()return new ConcreteProduct();public interface Product public class ConcreteProduct implements Product public ConcreteProduct()代码清单 7.简单工厂模式框架的源代码 5.2.3 工厂方法模式工厂方法模式 在简单工厂模式中,一个工厂类处于对产品类实例化调用的中心位置上,它决定那一个产品类应当被实例化,如同一个交通警察站在来往的车辆流中,决定放行那一个方向的车辆向那一个方向流动一样 而本节要讨论的工厂方法模式是简单工厂模式的进一步抽象化和推广 它比简单工厂模式聪明的

16、地方在于,它不再作为一个具体的交通警察的面貌出现,而是以交通警察局的面貌出现它把具体的车辆交通交给下面去管理换言之,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给子类去作处于工厂方法模式的中心位置上的类甚至都不去接触那一个产品类应当被实例化这种细节这种进一步抽象化的结果,是这种新的模式可以用来处理更加复杂的情形 现在,让我们继续考察我们的小花果园在简单工厂模式一节里,我们在后花园里引进了水果类植物,构造了简单工厂模式来处理,使用一个FruitGardener类来负责创立水果类的实例见下图 图 1.简单工厂模式FruitGardener 掌握所有水果类的生杀大权 在

17、这一节里,我们准备再次引进蔬菜类植物比如 西红柿(Tomato)土豆(Potato)西兰花(Broccoli)蔬菜与花和水果当然有共同点,可又有不同之处蔬菜需要喷洒(dust)杀虫剂(pesticide)除虫,不同的蔬菜需要喷洒不同的杀虫剂,等等怎么办呢?那么,再借用一下简单工厂模式不就行了?再设计一个专管蔬菜类植物的工厂类,比如 图 2.简单工厂模式VeggieGardener 掌握所有蔬菜类的生杀大权 这样做一个明显的不足点就是不够一般化和抽象化在 FruitGardener 和 VeggieGardener 类之间明显存在很多共同点,这些共同点应当抽出来一般化和框架化 这样一来,如果后花

18、园的主人决定再在园子里引进些树木类植物时,我们有框架化的处理方法本节所要引入的工厂方法模式就符合这样 的要求 有必要首先回顾一下简单工厂模式的定义,以便于比较 图 3.简单工厂模式的类图定义 从上图可以看出简单工厂模式涉及到以下的角色 工厂类(Creator)担任这个角色的是工厂方法模式的核心是与应用程序紧密相关的直接在应用程序调用下创立产品实例的那个类工厂类只有一个而且是具体的 产品(Product)担任这个角色的类是工厂方法模式所创立的对象的超类或它们共同拥有的接口 具体产品(Concrete Product)担任这个角色的类是工厂方法模式所创立的任何对象所属的类 工厂方法模式的定义工厂方

19、法模式的定义 我们给出工厂方法模式的类图定义如下 图 4.工厂方法模式的类图定义 从上图可以看出工厂方法模式涉及到以下的角色 抽象工厂接口(Creator)担任这个角色的是工厂方法模式的核心它是与应用程序无关的任何在模式中创立对象的工厂类必须实现这个接口 具体工厂类(Conrete Creator)担任这个角色的是与应用程序紧密相关的直接在应用程序调用下创立产品实例的那样一些类 产品(Product)担任这个角色的类是工厂方法模式所创立的对象的超类或它们共同拥有的接口 具体产品(Concrete Product)担任这个角色的类是工厂方法模式所创立的任何对象所属的类 工厂方法模式和简单工厂模式

20、在定义上的不同是很明显的 工厂方法模式的核心是一个抽象工厂 类,而不像简单工厂模式,把核心放在一个具体类上工厂方法模式可以允许很多具体的工厂类从抽象 工厂类继承下来,从而可以在实际上成为多个简单工厂模式的综合,从而推广了简单工厂模式 反过来讲,简单工厂模式是由工厂方法模式退化而来设想如果我们非常确定一个系统只需要一个具体的工厂类,那么就不妨把抽象工厂类合并到具体的工厂类中去 而这样一来,我们就退化到简单工厂模式了 与简单工厂模式中的情形一样的是ConcreteCreator 的 factory()方法返还的数据类型是一个接口 PlantIF而不是哪一个具体的产品类这种设计使得工厂类创立哪一个产

21、品类的实例细节完全封装在工厂类内部 工厂方法模式又叫多形性工厂模式 显然是因为具体工厂类都有共同的接口 或者都有共同的抽象超类 工厂方法模式在小花果园系统中的实现工厂方法模式在小花果园系统中的实现 现在让我们回到小花果园的系统里 看一看怎样发挥工厂方法模式的威力 解决需要接连 不断向小花果园引进不同类别的植物所带来的问题 首先我们需要一个抽象工厂类比如叫做 Gardener作为两个具体工厂类 FruitGardener 及 VeggieGardener 的超类 Gardener 的 factory()方法可以是抽象的留给子类去实现也可以是具体的在超类实现一部分功能再在子类实现剩余的功能我们选择

22、将 factory()做成抽象的主要是因为我们的系统是一个示范系统内容十分简单没有要在超类实现的任何功能 图 5.工厂方法模式在小花果园系统中的实现 抽象工厂类 Gardener 是工厂方法模式的核心但是它并不掌握水果类或蔬菜类的生杀大权相反地这项权力被交给子类即 VeggieGardener 及 FruitGardener package com.javapatterns.factorymethod;abstract public class Gardener public abstract PlantIF factory(String which)throws BadFruitExcept

23、ion;代码清单 1.超类 Gardener package com.javapatterns.factorymethod;public class VeggieGardener extends Gardener public PlantIF factory(String which)throws BadPlantException if(which.equalsIgnoreCase(tomato)return new Tomato();else if(which.equalsIgnoreCase(potato)return new Potato();else if(which.equalsI

24、gnoreCase(broccoli)return new Broccoli();else throw new BadPlantException(Bad veggie request);代码清单 2.子类 VeggieGardener package com.javapatterns.factorymethod;public class FruitGardener extends Gardener public PlantIF factory(String which)if(which.equalsIgnoreCase(apple)return new Apple();else if(whi

25、ch.equalsIgnoreCase(strawberry)return new Strawberry();else if(which.equalsIgnoreCase(grape)return new Grape();else throw new BadPlantException(Bad fruit request);代码清单 3.子类 FruitGardener package com.javapatterns.factorymethod;public class Broccoli implements VeggieIF,PlantIF public void grow()log(Br

26、occoli is growing.);public void harvest()log(Broccoli has been harvested.);public void plant()log(Broccoli has been planted.);private static void log(String msg)System.out.println(msg);public void pesticideDust()代码清单 4.蔬菜类 Broccoli其它的蔬菜类与 Broccoli 相似因此不再赘述 package com.javapatterns.factorymethod;publ

27、ic class Apple implements FruitIF,PlantIF public void grow()log(Apple is growing.);public void harvest()log(Apple has been harvested.);public void plant()log(Apple has been planted.);private static void log(String msg)System.out.println(msg);public int getTreeAge()return treeAge;public void setTreeA

28、ge(int treeAge)this.treeAge=treeAge;private int treeAge;代码清单 5.水果类 Apple与一节里的 Apple 类相比唯一的区别就是多 实现了一个接口 PlantIF其它的水果类与 Apple 相似因此不再赘述 package com.javapatterns.factorymethod;public class BadPlantException extends Exception public BadPlantException(String msg)super(msg);代码清单 6.例外类 BadPlantException 工厂

29、方法模式应该在什么情况下使用工厂方法模式应该在什么情况下使用 既然工厂方法模式与简单工厂模式的区别很是微妙 那么应该在什么情况下使用工厂方法 模式又应该在什么情况下使用简单工厂模式呢 一般来说 如果你的系统不能事先确定那一个产品类在哪一个时刻被实例化 从而需要将实例化的细节局域化 并封装起来以分割实例化及使用实例的责任时 你就需要考虑使用 某一种形式的工厂模式 在我们的小花果园系统里 我们必须假设水果的种类随时都有可能变化 我们必须能够在引入新的水果品种时能够很少改动程序就可以适应变化以后的情况因此我们显然 需要某一种形式的工厂模式 如果在发现系统只用一个产品类层次(hierarchy)就可以

30、描述所有已有的产品类以及可预见的未来可能引进的产品类时 简单工厂模式是很好的解决方案 因为一个单一产品类等 级只需要一个单一的实的工厂类 然而当发现系统只用一个产品类层次不足以描述所有的产品类,包括以后可能要添加的新的产品类时 就应当考虑采用工厂方法模式 由于工厂方法模式可以容许多个具体的工厂类以每一个工厂类负责每一个产品类等级因此这种模式可以容纳所有的产品等级 在我们的小花果园系统里不只有水果种类的植物,而且有蔬菜种类的植物换言之存在不止一个产品类层次而且产品类层次的数目也随时都有可能变化因此简单工厂模式不能满足需要为解决向题,我们显然需要工厂方法模式 关于模式的实现关于模式的实现 在实现工

31、厂方法模式时有下面一些值得讨论的地方 第一丶在图四的类图定义中可以对抽象工厂(Creator)做一些变通变通的种类有抽象工厂(Creator)不是接口而是抽象类一般而言抽象类不提供一个缺省的工厂方法 这样可 以有效地解决怎样实例化事先不能预知的类的问题 抽象工厂(Creator)本身是一个具体类并提供一个缺省的工厂方法 这样当最初的设计者所预见的实例化不能满足需要时后来的设计人员就可以用具体工厂类的 factory()方法来重置(Override)父类中 factory()方法 第二丶在经典的工厂方法模式中factory()方法是没有参量的在本文举例时加入了参量这实际上也是一种变通 第三丶在给

32、相关的类和方法取名字时应当注意让别人一看即知你是在使用工厂模式 关于模式的实现 在实现工厂方法模式时有下面一些值得讨论的地方 第一丶在图四的类图定义中可以对抽象工厂(Creator)做一些变通变通的种类有 抽象工厂(Creator)不是接口而是抽象类 一般而言 抽象类不提供一个缺省的工厂方法 这样可 以有效地解决怎样实例化事先不能预知的类的问题 抽象工厂(Creator)本身是一个实类并提供一个缺省的工厂方法 这样当最初的设计者所预见的 实例化不能满足需要时后来的设计人员就可以用实工厂类的 factory()方法来置换(Override)父类 中 factory()方法 第二丶在经典的工厂方法

33、模式中factory()方法是没有参量的在本文举例时加入了参量这实际 上也是一种变通 第三丶在给相关的类和方法取名字时应当注意让别人一看即知你是在使用工厂模式 5.2.4 抽象工厂模式抽象工厂模式 工厂模式有简单工厂模式,工厂方法模式和抽象工厂模式几种形态其中简单工厂模式和工厂方法 模式已经在前面作过介绍在这里我们来介绍抽象工厂模式 抽象工厂模式是所有形态的工厂模式中最为抽象和最具广泛性的一种形态 抽象工厂模式的定义抽象工厂模式的定义 抽象工厂模式是工厂方法模式的进一步扩广化和抽象化 我们给出抽象工厂模式的类图定义如 下 图 1.抽象工厂模式的类图定义 从上图可以看出简单工厂模式涉及到以下的角

34、色 抽象工厂(AbstractFactory)类或接口担任这个角色的是工厂方法模式的核心它是与应用程序无关的任何在模式中创立对象的工厂 类必须实现这个接口或继承这个类 具体工厂类(Conrete Factory)担任这个角色的是与应用程序紧密相关的直接在应用程序调用下创立产品实例的那样一些类 抽象产品(Abstract Product)担任这个角色的类是工厂方法模式所创立的对象的父类或它们共同拥有的接口 具体产品(Concrete Product)担任这个角色的类是工厂方法模式所创立的任何对象所属的类 怎么这个类图和工厂方法模式的类图看起来是一样的?是的图是一样的但是含义有很大的不同必须指出在

35、抽象工厂模式中抽象产品(AbstractProduct)可能是一个或多个 从而构成一个或多个产品族(Product Family)在只有一个产品族的情况下抽象工厂模式实际上退化到工厂方法模式 在什么情形下应当使用抽象工厂模式在什么情形下应当使用抽象工厂模式 在以下情况下应当考虑使用抽象工厂模式 首先一个系统应当不依赖于产品类实例被创立组成和表示的细节这对于所有形态的工厂模式都是重要的 其次这个系统的产品有多于一个的产品族 第三 同属于同一个产品族的产品是设计成在一起使用的 这一约束必须得在系统的设计中体现出来 最后不同的产品以一系列的接口的面貌出现从而使系统不依赖于接口实现的细节 其中第二丶第

36、三个条件是我们选用抽象工厂模式而非其它形态的工厂模式的关键性条件 抽象工厂模式在小花果园系统中的实现抽象工厂模式在小花果园系统中的实现 现在如果在南方购买了一个别墅这意味着我们有两处小花园需要照料一处在北方地区另一处在亚热带地区 抽象工厂模式正好适用于我们的情况 图 3.抽象工厂模式应用于小花果园系统中三种不同的背景颜色可以区分工厂类蔬菜类(第一产品族)和水果类的类图(第二产品族)两处花园就相当于两个产品族显然给北方花园的植物是要种植在一起的给南方花园的植物是要另种植在一起的 这种分别应当体现在系统的设计上面 这就满足了应当使用 抽象工厂模式的第二和第三个条件 package com.java

37、patterns.abstractfactory;public interface Gardener 代码清单 1.接口 Gardener package com.javapatterns.abstractfactory;public class NorthenGardener implements Gardener public VeggieIF createVeggie(String name)return new NorthernVeggie(name);public FruitIF createFruit(String name)return new NorthernFruit(nam

38、e);代码清单 2.实工厂类 NorthenGardener package com.javapatterns.abstractfactory;public class TropicalGardener implements Gardener public VeggieIF createVeggie(String name)return new TropicalVeggie(name);public FruitIF createFruit(String name)return new TopicalFruit(name);代码清单 3.实工厂类 TropicalGardener package

39、 com.javapatterns.abstractfactory;public interface VeggieIF 代码清单 4.接口 VeggieIF package com.javapatterns.abstractfactory;public class NorthernVeggie implements VeggieIF public NorthernVeggie(String name)this.name=name;public String getName()return name;public void setName(String name)this.name=name;p

40、rivate String name;代码清单 5.实产品类 NorthernVeggie实产品类 NorthernFruit 与此极为类似故略去 package com.javapatterns.abstractfactory;public class TropicalVeggie implements VeggieIF public TropicalVeggie(String name)this.name=name;public String getName()return name;public void setName(String name)this.name=name;privat

41、e String name;代码清单 6.实产品类 TropicalVeggie实产品类 TropicalFruit 与此极为类似故略去 笔者对植物的了解有限 为免遗笑大方 在上面的系统里采用了简化处理 没有给出高纬 度和低纬度的水果类或蔬菜类的具体名称 抽象工厂模式的另一个例子抽象工厂模式的另一个例子 这个例子讲的是微型计算机的生产产品族有两个PC(IBM 系列)和 Mac(MacIntosh 系列)显然 我们应该使用抽象工厂模式而不是工厂方法模式因为后者适合于处理只有一个产品族的情形 图 4.抽象工厂模式应用于微型计算机生产系统中两种不同的背景颜色可以区分两类产品族及其对应的实工厂类 关于

42、模式的实现 在抽象实现工厂模式时有下面一些值得注意的技巧 第一丶具体工厂类可以设计成单态类很显然在小花果园系统中我们只需要 NorthenGardener 和 TropicalGardener 的一个实例就可以了关于单态类的知识请见 第二丶在实现抽象工厂模式时产品类往往分属多于一个的产品族而针对每一族都需要一个具体工厂类在很多情况下几个具体工厂类都彼此相象只有些微的差别 这时笔者建议使用原型(Prototype)模式这一模式会在以后介绍届时作者会进一步阐述这一点 第三丶设计更加灵活的具体工厂以微型计算机生产系统为例PCProducer 是一个具体工厂类 它的不灵活之处在于 每一种产品都有一个工

43、厂方法 CPU 有 createCPU()RAM 有createRAM()等等如果一个已有的系统需要扩充比如增加硬盘这一新产品我们就需要增加一系列的接口(createHD()丶类(HD,PCHD,MacHD)和方法这似乎不很理想 一个解决的办法是把 createCPU(),createRAM(),createHD()这几个方法合并为一个createPart(String type)方法这个合并后的方法返还一个 Part 接口所有的产品都要实现这一接口而 CPURAM和 HD 接口则不再需要了每一个实产品都需要有一个属性表明它们的种类是 CPURAM和 HD 这样做的结果是数据类型的丰富结构被扁

44、平化了客户端拿到的永远是一个 Part 接口这对客户端而言不很安全 第四丶抽象工厂类可以配备静态方法以返还具体工厂设计的方法有两种 一种是以一个静态方法按照参量的值返回所对应的实工厂静态方法的数据类型是抽象方法类 另一种是以每一个具体工厂类都配备一个静态方法其数据类型是该具体工厂类 import com.bruceeckel.test.*;interface Obstacle void action();interface Player void interactWith(Obstacle o);class Kitty implements Player public void interac

45、tWith(Obstacle ob)System.out.print(Kitty has encountered a);ob.action();class KungFuGuy implements Player public void interactWith(Obstacle ob)System.out.print(KungFuGuy now battles a);ob.action();class Puzzle implements Obstacle public void action()System.out.println(Puzzle);class NastyWeapon imple

46、ments Obstacle public void action()System.out.println(NastyWeapon);/The Abstract Factory:interface GameElementFactory Player makePlayer();Obstacle makeObstacle();/Concrete factories:class KittiesAndPuzzles implements GameElementFactory public Player makePlayer()return new Kitty();public Obstacle mak

47、eObstacle()return new Puzzle();class KillAndDismember implements GameElementFactory public Player makePlayer()return new KungFuGuy();public Obstacle makeObstacle()return new NastyWeapon();public class GameEnvironment private GameElementFactory gef;private Player p;private Obstacle ob;public GameEnvi

48、ronment(GameElementFactory factory)gef=factory;p=factory.makePlayer();ob=factory.makeObstacle();public void play()p.interactWith(ob);public static class Test extends UnitTest GameElementFactory kp=new KittiesAndPuzzles(),kd=new KillAndDismember();GameEnvironment g1=new GameEnvironment(kp),g2=new Gam

49、eEnvironment(kd);/These just ensure no exceptions are thrown:public void test1()g1.play();public void test2()g2.play();public static void main(String args)Test t=new Test();t.test1();t.test2();/:5.2.5 单态模式单态模式 一个单态类只可有一个实例这样的类常用来进行资源管理 需要管理的资源包括软件外部资源譬如每台计算机可以有若干个打印机但只能有 一个打印处理器软件 每台计算机可以有若干传真卡 但是只应

50、该有一个传真软件管理传真每台计算机可以有若干通讯端口 你的软件应当集中管理这些通讯端口 以避免同时一个通讯端口被两个请求同时调用 需要管理的资源包括软件内部资源譬如大多数的软件都有一个(甚至多个)属性 properties文件 存放系统配置这样的系统应当有一个对象来管理一个属性文件 很多软件都有数据库一般而言 整个软件应当使用一个联接通道而不是任意在需要 时就新打开一个联接通道 需要管理的软件内部资源也包括譬如负责纪录网站来访人数的部件,记录软件系统内部事 件出错 信息的部件或是进行系统表现监查的的部件,等等这些部件都必须集中管 理不可政出多头 单态类的特性单态类的特性 综合而言 1单态类只可

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

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

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

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁