【Java开源代码栏目提醒】:网学会员为广大网友收集整理了,面向对象设计模式 工厂模式 二 - 互联网,希望对大家有所帮助!
面向对象设计模式 工厂模式 二 面向对象设计模式--工厂模式二2010-08-19 2232 一.程序设计目标 我们组写了个简单的水果生产程序描述农场种植水果的过程旨在通过此次设计更进一步了解工程
设计模式加强编程的结构化能力。
开发环境JDK1.5 开发工具JBuilder 2006 二.程序设计介绍 1.程序结构 我们组为一个水果公司写了个简单的生产
程序该公司专门向市场销售各类水果。
我们为程序建立了一个名为farm的工程程序结构比较简单总共有7个类并且都放在一个默认的包中。
其层次结构可从下图体现出来 对各个类的说明 Fruit类水果接口实现水果方法 Apple类苹果类实现Fruit接口 Grape类葡萄类实现Fruit接口 Strawberry类草莓类实现Fruit接口 FruitGardener类园丁类可种植各种水果 BadFruitException类要种植的水果不在公司经营的水果范围之内抛出种植异常 PlantFruit类实现main方法 2.程序设计步骤 在这个系统里需要描述下列的水果 葡萄Grape 草莓Strawberry 苹果Apple 水果与其他的植物有很大的不同就是水果最终是可以采摘食用的。
那么一个自然的 作法就是建立一个各种水果都适用的接口以便与农场里的其他植物区分开。
如下图所示。
水果接口规定出所有的水果必须实现的接口包括任何水果类必须具备的方法种植plant生长grow以及收获harvest。
接口Fruit的类图如下所示。
这个水果接口的源
代码如下所示。
代码清单1接口Fruit的源
代码 public interface Fruit //生长 void grow //收获 void harvest //种植 void plant 描述苹果的Apple类的源
代码的类图如下所示。
Apple类是水果类的一种因此它实现了水果接口所声明的所有方法。
另外由于苹果是多年生植物因此多出一个treeAge性质描述苹果树的树龄。
下面是这个苹果类的源
代码。
代码清单2类Apple的源
代码 public class Apple implements Fruit private int treeAge //生长 public void grow logApple is growing. //收获 public void harvest logApple has been harvested. //种植 public void plant logApple has been planted. //辅助方法 public static void logString msg System.out.printlnmsg //树龄的取值方法 public int getTreeAge return treeAge //树龄的赋值方法 public void setTreeAgeint treeAge this.treeAgetreeAge 同样Grape类是水果类的一种也实现了Fruit接口所声明的所有的方法。
但由于葡萄分有籽和无籽两种因此比通常的水果多出一个seedless性质如下图所示。
葡萄类的源
代码如下所示。
可以看出Grape类同样实现了水果接口从而是水果类型的一种子类型。
代码清单3类Grape的源
代码 public class Grape implements Fruit private boolean seedless //生长 public void grow logGrape is growing. //收获 public void harvest logGrape has been harvested. //种植 public void plant logGrape has been planted. //辅助方法 public static void logString msg System.out.printlnmsg //有无籽的取值方法 public boolean getSeedless return seedless //有无籽的赋值方法 public void setSeedlessboolean seedless this.seedlessseedless 下图所示是Strawberry类的类图。
Strawberry类实现了Fruit接口因此也是水果类型的子类型其源
代码如下所示。
代码清单4类Strawberry的源
代码 public class Strawberry implements Fruit //生长 public void grow logStrawberry is growing. //收获 public void harvest logStrawberry has been harvested. //种植 public void plant logStrawberry has been planted. //辅助方法 public static void logString msg System.out.printlnmsg 农场的园丁也是系统的一部分自然要由一个合适的类来代表。
这个类就FruitGardener类其结构由下面的类图描述。
FruitGardener类会根据客户端的要求创建出不同的水果对象比如苹果Apple葡萄Grape或草莓Strawberry的实例。
而如果接到不合法的要求FruitGardener类会抛出BadFruitException异常如下图所示。
园丁类的源
代码如下所示。
代码清单5FruitGardener类的源
代码 public class FruitGardener //静态工厂方法 public static Fruit factoryString whichthrows BadFruitException ifwhich.equalsIgnoreCaseapple return new Apple else ifwhich.equalsIgnoreCasestrawberry return new Strawberry else ifwhich.equalsIgnoreCasegrape return new Grape else throw new BadFruitExceptionBad fruit request 可以看出园丁类提供了一个静态工厂方法。
在客户端的调用下这个方法创建客户端所需要的水果对象。
如果客户端的请求是
系统所不支持的工厂方法就会抛出一个BadFruitException异常。
这个异常类的源
代码如下所示。
代码清单6BadFruitException类的源
代码 public class BadFruitException extends Exception public BadFruitExceptionString msg supermsg 在使用时客户端只需调用FruitGardener的静态方法factory即可。
请见下面的示意性客户端源
代码。
代码清单7实现种植即Main的实现 public class PlantFruit public PlantFruit public static void mainString args PlantFruit plantfruitnew PlantFruit try //种植葡萄 FruitGardener.factorygrape.plant FruitGardener.factorygrape.grow FruitGardener.factorygrape.harvest System.out.println //种植苹果 FruitGardener.factoryapple.plant FruitGardener.factoryapple.grow FruitGardener.factoryapple.harvest System.out.println //种植草莓 FruitGardener.factorystrawberry.plant FruitGardener.factorystrawberry.grow FruitGardener.factorystrawberry.harvest System.out.println catchBadFruitException e 到此为止我们的简单程序已经设计完成我们可以通过创建FruitGardener对象来完成水果的种植无论你要种什么只需调用对象中的factory方法。
输出结果如下 三.简单工厂模式的定义 简单工厂模式是类的创建模式又叫做静态工厂方法Static Factory Method模式。
简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例。
四.简单工厂模式的结构 简单工厂模式是类的创建模式这个模式的一般性结构如下图所示。
角色与结构 简单工厂模式就是由一个工厂类可以根据传入的参量决定创建出哪一种产品类的实例。
下图所示为以一个示意性的实现为例说明简单工厂模式的结构。
从上图可以看出简单工厂模式涉及到工厂角色、抽象产品角色以及具体产品角色等 三个角色 1工厂类Creator角色担任这个角色的是工厂方法模式的核心含有与应用紧 密相关的商业逻辑。
工厂类在客户端的直接调用下创建产品对象它往往由一个 具体
Java类实现。
2抽象产品Product角色担任这个角色的类是工厂方法模式所创建的对象的父 类或它们共同拥有的接口。
抽象产品角色可以用一个
Java接口或者
Java抽象类 实现。
3具体产品Concrete Product角色工厂方法模式所创建的任何对象都是这个角 色的实例具体产品角色由一个具体
Java类实现。
工厂类的示意性源
代码如下所示。
可以看出这个工厂方法创建了一个新的具体产品的实例并返还给调用者。
代码清单8Creator类的源
代码 public class Creator //静态工厂方法 public static Product factory return new ConcreteProduct 抽象产品角色的主要目的是给所有的具体产品类提供一个共同的类型在最简单的情况下可以简化为一个标识接口。
所谓标识接口就是没有声明任何方法的空接口。
代码清单9抽象角色Product接口的源
代码 public interface Product 具体产品类的示意性源
代码如下。
代码清单10具体产品角色ConcreteProduct类的源
代码 public class ConcreteProduct implements Product public ConcreteProduct 虽然在这个简单的示意性实现里面只给出了一个具体产品类但是在实际应用中一般都会遇到多个具体产品类的情况。
五.简单工厂模式的实现 1.多层次的产品结构 在真实的系统中产品可以形成复杂的等级结构比如下图所示的树状结构上就有多个抽象产品类和具体产品类。
这个时候简单工厂模式采取的是以不变应万变的策略一律使用同一个工厂类。
如下图所示。
图中从Factory类到各个Product类的虚线代表创建依赖关系从Client到其他类的联线是一般依赖关系。
这样做的好处是设计简单产品类的等级结构不会反映到工厂类中来从而产品类的等级结构的变化也就不会影响到工厂类。
但是这样做的缺点是增加新的产品必将导致工厂类的修改。
2.使用
Java接口或者
Java抽象类 如果模式所产生的具体产品类彼此之间没有共同的商业逻辑那么抽象产品角色可以由一个
Java接口扮演相反如果这些具体产品类彼此之间确有共同的商业逻辑那么这些公有的逻辑就应当移到抽象角色里面这就意味着抽象角色应当由一个抽象类扮演。
在一个类型的等级结构里面共同的
代码应当尽量向上移动以达到共享的目的如下图所示。