`
edicky
  • 浏览: 39204 次
  • 来自: ...
社区版块
存档分类
最新评论

Java工厂设计模式

阅读更多

一.   程序设计目标

 

    我们组写了个简单的水果生产程序,描述农场种植水果的过程,旨在通过此次设计更进一步了解工程设计模式,加强编程的结构化能力。

    开发环境: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() {

    log("Apple is growing...");

  }

 

// 收获

  public void harvest() {

    log("Apple has been harvested.");

  }

 

// 种植

  public void plant() {

    log("Apple has been planted.");

  }

 

// 辅助方法

  public static void log(String msg) {

    System.out.println(msg);

  }

 

// 树龄的取值方法

  public int getTreeAge() {

    return treeAge;

  }

 

// 树龄的赋值方法

  public void setTreeAge(int treeAge) {

    this.treeAge = treeAge;

  }

}

同样, Grape 类是水果类的一种,也实现了 Fruit 接口所声明的所有的方法。但由于葡萄分有籽和无籽两种,因此,比通常的水果多出一个 seedless 性质,如下图所示。

 

葡萄类的源代码如下所示。可以看出, Grape 类同样实现了水果接口,从而是水果类型的一种子类型。

 

代码清单 3 :类 Grape 的源代码

public class Grape

    implements Fruit {

  private boolean seedless;

// 生长

  public void grow() {

    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 getSeedless() {

    return seedless;

  }

 

// 有无籽的赋值方法

  public void setSeedless(boolean seedless) {

    this.seedless = seedless;

  }

}

下图所示是 Strawberry 类的类图。

 

Strawberry 类实现了 Fruit 接口,因此,也是水果类型的子类型,其源代码如下所示。

 

代码清单 4 :类 Strawberry 的源代码

public class Strawberry

    implements Fruit {

// 生长

  public void grow() {

    log("Strawberry is growing...");

  }

 

// 收获

  public void harvest() {

    log("Strawberry has been harvested.");

  }

 

// 种植

  public void plant() {

    log("Strawberry has been planted.");

  }

 

// 辅助方法

  public static void log(String msg) {

    System.out.println(msg);

  }

}

农场的园丁也是系统的一部分,自然要由一个合适的类来代表。这个类就 FruitGardener 类,其结构由下面的类图描述。

 

FruitGardener 类会根据客户端的要求,创建出不同的水果对象,比如苹果( Apple ),葡萄( Grape )或草莓( Strawberry )的实例。而如果接到不合法的要求, FruitGardener 类会抛出 BadFruitException 异常,如下图所示。

 

园丁类的源代码如下所示。

 

代码清单 5 FruitGardener 类的源代码

public class FruitGardener {

// 静态工厂方法

  public static Fruit 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");

    }

  }

}

 

可以看出,园丁类提供了一个静态工厂方法。在客户端的调用下,这个方法创建客户端所需要的水果对象。如果客户端的请求是系统所不支持的,工厂方法就会抛出一个 BadFruitException 异常。这个异常类的源代码如下所示。

 

代码清单 6 BadFruitException 类的源代码

 

public class BadFruitException

    extends Exception {

  public BadFruitException(String msg) {

    super(msg);

  }

}

 

在使用时,客户端只需调用 FruitGardener 的静态方法 factory() 即可。请见下面的示意性客户端源代码。

 

代码清单 7 :实现种植即Main() 的实现

public class PlantFruit {

  public PlantFruit() {

  }

 

  public static void main(String[] args) {

    PlantFruit plantfruit = new PlantFruit();

    try {

      // 种植葡萄

       FruitGardener.factory("grape").plant();

      FruitGardener.factory("grape").grow();

      FruitGardener.factory("grape").harvest();

      System.out.println("==================================");

     

      // 种植苹果

      FruitGardener.factory("apple").plant();

      FruitGardener.factory("apple").grow();

      FruitGardener.factory("apple").harvest();

      System.out.println("==================================");

     

      // 种植草莓

      FruitGardener.factory("strawberry").plant();

      FruitGardener.factory("strawberry").grow();

      FruitGardener.factory("strawberry").harvest();

      System.out.println("==================================");

    }

    catch (BadFruitException e) {

    }

  }

}

到此为止,我们的简单程序已经设计完成,我们可以通过创建FruitGardener 对象来完成水果的种植,无论你要种什么,只需调用对象中的factory() 方法。输出结果如下:

 

 

 

三.简单工厂模式的定义

 

简单工厂模式是类的创建模式,又叫做静态工厂方法( Static Factory Method )模式。简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例。

 

四. 简单工厂模式的结构

 

简单工厂模式是类的创建模式,这个模式的一般性结构如下图所示。

 

角色与结构

简单工厂模式就是由一个工厂类可以根据传入的参量决定创建出哪一种产品类的实例。下图所示为以一个示意性的实现为例说明简单工厂模式的结构。

 

从上图可以看出,简单工厂模式涉及到工厂角色、抽象产品角色以及具体产品角色等

三个角色:

1 工厂类( Creator )角色:担任这个角色的是工厂方法模式的核心,含有与应用紧

密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个

具体 Java 类实现。

2 抽象产品( Product )角色:担任这个角色的类是工厂方法模式所创建的对象的父

类,或它们共同拥有的接口。抽象产品角色可以用一个 Java 接口或者 Java 抽象类

实现。

3 具体产品( Concrete Product )角色:工厂方法模式所创建的任何对象都是这个角

色的实例,具体产品角色由一个具体 Java 类实现。

 

工厂类的示意性源代码如下所示。可以看出,这个工厂方法创建了一个新的具体产品的实例并返还给调用者。

 

代码清单 8 Creator 类的源代码

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 接口扮演;相反,如果这些具体产品类彼此之间确有共同的商业逻辑,那么这些公有的逻辑就应当移到抽象角色里面,这就意味着抽象角色应当由一个抽象类扮演。在一个类型的等级结构里面,共同的代码应当尽量向上移动,以达到共享的目的,如下图所示。

 

 

六. 模式的优点和缺点

 

1 . 模式的优点

模式的核心是工厂类。这个类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例。而客户端则可以免除直接创建产品对象的责任,而仅仅负责“消费”产品。简单工厂模式通过这种做法实现了对责任的分割。

2 . 模式的缺点

正如同在本章前面所讨论的,当产品类有复杂的多层次等级结构时,工厂类只有它自

己。以不变应万变,就是模式的缺点。这个工厂类集中了所有的产品创建逻辑,形成一个无所不知的全能类,有人把这种类叫做上帝类( God Class )。 如果这个全能类代表的是农场的一个具体园丁的话,那么这个园丁就需要对所有的产品负责,成了农场的关键人物,他什么时候不能正常工作了,整个农场都要受到 影响。将这么多的逻辑集中放在一个类里面的另外一个缺点是,当产品类有不同的接口种类时,工厂类需要判断在什么时候创建某种产品。这种对时机的判断和对哪 一种具体产品的判断逻辑混合在一起,使得系统在将来进行功能扩展时较为困难。这一缺点在工厂方法模式中得到克服。

由于简单工厂模式使用静态方法作为工厂方法,而静态方法无法由子类继承,因此,工厂角色无法形成基于继承的等级结构。这一缺点会在工厂方法模式中得到克服。

 

七.个人体会  

     设计模式实际上是良好的OO 思想的一种提炼。每一种设计模式后面都体现了一种良好的OO 思路,这些思路对于解决软件中常见的“change ” 问题有很大的适应性,而每种模式又有自己独特的解决思路,带有一定的通用性。而组合各种模式又可以解决许多常见问题。不可否认的是,还存在一些未经总结的 设计模式。实际上,你自己也可以总结一些模式出来。无论怎样,设计模式仍然是面向对象,它不是新东西,也没有必要言必称设计模式 似乎不懂设计模式就落伍了,但给OO 的开发者提供一个言简意赅的沟通桥梁。

设计模式告诉了我们什么是好的OO 思想,思考如何更好的应用OO 的思想 虽然还是那几个耳熟能详的术语:封装、继承、组合、多态。

设计模式首先是对传统的OO 使用方法的矫正:如针对接口编程而不是实现;优先使用组合,而不是继承。其次是在原来理解上的突破:封装是对变化而言的,不仅仅是属性和方法的集合。类不仅是现实事物的抽象,同时它还具有责任。更有创新:依赖式注入。

模式不是万能的,也并不总能完美地解决问题,因此每种模式都包括了影响的信息。在应用模式之前,我们必须先分析问题的情境,并评估模式的影响,再决定是否采用模式,采用哪一种模式。也就是说,理解、分析模式,和实现模式一样重要

八.建议

   (1) 使用更加通俗易懂的语言解释设计模式,并用完整的代码实例辅以说明。代码的演示时间应延长点,好让学生看清,看懂代码。

    (2) 在学生需要的时候给学生补充一点java 知识,有些同学专注于其他语言, 对于java 也不太懂,听起课来一头雾水,这时候来点知识补充还是必要的。

分享到:
评论

相关推荐

    java工厂设计模式

    综上所述,"java工厂设计模式"是Java编程中一个重要的设计原则,它利用接口和接口的实现来确保代码的灵活性和可扩展性。通过创建工厂类来生产符合特定接口的产品,我们可以实现对象的动态创建,从而提高系统的可维护...

    java工厂设计模式之简单工厂

    **Java工厂设计模式之简单工厂** 简单工厂设计模式是一种创建型设计模式,它提供一个创建对象的静态方法,客户端可以通过这个静态方法获取所需的具体产品,而无需了解这些产品的具体实现。这种模式的主要目的是将...

    Java 工厂设计模式例题

    例题简单的阐述了Java工厂模式的概念,有利于读者更好地了解Java工厂模式

    java工厂设计模式.doc

    java工厂设计模式

    java工厂设计模式讲解+例子

    java工厂设计模式讲解+例子,三种工厂模式的讲解,简单工厂、工厂方法、抽象工厂

    java设计模式之工厂模式

    java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式...

    设计模式之简单工厂模式

    **简单工厂模式**是软件设计模式中的一种基础模式,它属于创建型模式,主要用于简化对象的创建过程。在简单工厂模式中,一个专门的工厂类负责创建对象,客户端通过调用工厂类的方法来获取所需的对象,而无需关心具体...

    Java常用设计模式

    例如,`java工厂设计模式.doc`可能详细介绍了这些不同类型的工厂模式及其应用场景,并通过实例展示了如何在Java中实现它们。 接下来是单例模式。单例模式确保一个类只有一个实例,并提供一个全局访问点。这种模式在...

    Java 经典设计模式讲解以及项目实战

    Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...

    设计模式之java工厂模式

    "设计模式之java工厂模式"是关于如何优雅地创建对象的一种经典设计模式,它属于创建者模式类别。创建者模式主要关注对象的创建,而工厂模式则在其中扮演着重要角色,因为它提供了一种抽象的方式来创建对象,从而使...

    java 设计模式 mvc模式 单例模式 代理 工厂 简单工厂

    在软件开发中,设计模式是解决常见问题的模板或最佳实践,它们被广泛应用于Java和其他面向对象编程语言中。以下是对标题和描述中提到的一些关键设计模式的详细解释: 1. **MVC模式(Model-View-Controller)**:这...

    Java设计模式之工厂模式(Factory模式)介绍

    **工厂模式**是一种常见的设计模式,它在Java中被广泛应用于创建对象实例。工厂模式的主要目的是将对象的创建过程封装起来,使得代码更加灵活且易于维护。通过使用工厂模式,我们可以将实例化对象的责任从客户端代码...

    Java设计模式之工厂模式实现方法详解

    Java设计模式之工厂模式实现方法详解 工厂模式是 Java 设计模式中的一种重要模式,它提供了一种创建对象的接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。工厂模式主要有三种:简单工厂模式、...

    Java设计模式——工厂设计模式详解

    Java设计模式——工厂设计模式详解 在软件设计中,工厂设计模式是一种常用的设计模式,主要用于实例化有共同接口的类。Java设计模式——工厂设计模式是Java中的一种常用的设计模式,主要用于实例化有共同接口的类。...

    重学java的设计模式

    Java作为一门广泛应用的开发语言,其设计模式的应用对于提高代码质量、可维护性和可扩展性至关重要。本文将着重探讨创建型模式、结构型模式和行为模式这三大类设计模式,并结合六项设计原则进行深入解析。 首先,...

    JAVA 设计模式 工厂模式 代理模式 迭代模式 责任链模式 源码

    以下是关于JAVA设计模式中提及的四种模式——工厂模式、代理模式、迭代器模式以及责任链模式的详细说明。 1. **工厂模式**:工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,当创建...

    JAVA设计模式(java设计)

    Java设计模式是面向对象编程领域中的重要概念,它是一套被广泛接受并实践的解决软件设计问题的经验总结。设计模式并非具体的代码或库,而是一种在特定情境下为了解决常见问题而制定的通用解决方案的描述。它们描述了...

    java版本的设计模式的实现demo

    在Java编程中,运用合适的设计模式可以提高代码的可维护性、可扩展性和可复用性。以下是关于Java版本设计模式实现demo的一些补充说明: 1. 设计模式分类 设计模式通常分为三大类:创建型模式、结构型模式和行为型模式...

    设计模式单例模式和工厂模式综合应用

    "设计模式单例模式和工厂模式综合应用"的主题聚焦于两种常用的设计模式:单例模式和工厂模式,并探讨它们如何协同工作来实现高效、灵活的代码结构。这个主题尤其适用于Java编程语言,因为Java的面向对象特性使得设计...

Global site tag (gtag.js) - Google Analytics