Java设计模式.pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《Java设计模式.pdf》由会员分享,可在线阅读,更多相关《Java设计模式.pdf(58页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 设计 模式
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内