skywang12345

导航

 

 

概要

本章介绍"简单工厂模式"。内容包括:
简单工厂模式简介
简单工厂模式代码模型
简单工厂模式示例

说明:(01) 本文是在《Java与模式》的学习总结文章! (02) 文章中的UML的相关内容(包括类图说明绘图工具等),可以参考"UML系列" 文章。

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3526186.html

 

简单工厂模式简介

简单工厂模式(Simple Factory),又被称为"静态工厂方法模式"。它属于"创建模式"(创建对象的模式),并且是"工厂方法"模式的一种特殊实现。
通常,我们利用简单工厂模式来进行类的创建。例如,获取线程池对象,就是通过简单工厂模式来实现的。它的结构图如下所示:

简单工厂模式的结构共包括3个组成部分:工厂(Factory)抽象产品(Product)具体产品(ConcreteProduct)

 

1. 工厂 -- 工厂是简单工厂模式的核心,提供了对外接口。客户端或其它程序要获取Product对象,都是通过Factory的接口来获取的。

2. 抽象产品 -- 抽象产品是(许多)不同产品抽象出来的。Product可以是接口或者抽象类。

3. 具体产品 -- 工厂中返回的产品对象,实际上是通过ConcreteProduct来创建的。

 

 

简单工厂模式代码模型

public class Factory {
    public static Product newInstance() {
        return new ConcreteProduct();
    }
}
public abstract Product {
}
public class ConcreteProduct extends Product {
    public ConcreteProduct() {}
}

模型的类图

 

简单工厂模式示例

假设现在有一个水果工厂,能够生成各种各样的水果。目前能生产的水果包括苹果,葡萄和草莓。
我们通过"简单工厂模式"描述该问题,它的UML类图如下:

1. 工厂类
工厂类是"FruitFactory"。FruitFactory是水果工厂,水果工厂会生成水果。
FruitFactory的源码

 1 public class FruitFactory {
 2 
 3     public static Fruit newInstance(String name) 
 4         throws BadFruitException {
 5         // 如果name等于"apple"(忽略大小写),则返回苹果。
 6         if ("apple".equalsIgnoreCase(name)) {
 7             return new Apple();
 8         // 如果name等于"grape"(忽略大小写),则返回葡萄。
 9         } else if ("grape".equalsIgnoreCase(name)) {
10             return new Grape();
11         // 如果name等于"strawberry"(忽略大小写),则返回草莓。
12         } else if ("strawberry".equalsIgnoreCase(name)) {
13             return new Strawberry();
14         // 其它情况,则抛出异常。
15         } else {
16             throw new BadFruitException("Bad fruit request!");
17         }
18     }
19 }

 

2. 抽象产品类
Product类是"Fruit"。Fruit代表水果,它是抽象类,包含水果的基本特征:生长,种植,收获。
Fruit的源码

1 public abstract class Fruit {
2     abstract void grow();    // 生长
3     abstract void harvest(); // 收获
4     abstract void plant();   // 种植
5 }

 

3. 具体产品类
具体产品类是"Apple", "Grape"和"Strawberry"。它们是3种具体的水果,分别代表苹果,葡萄和草莓。
Apple的源码

 1 // Apple实现Fruit的函数接口,并且Apple中有私有成员age和私有方法log。
 2 public class Apple extends Fruit {
 3     private int age;
 4 
 5     public void grow() {
 6         log("Apple grow()");
 7     }
 8     public void harvest() {
 9         log("Apple harvest()");
10     }
11     public void plant() {
12         log("Apple plant()");
13     }
14     public void setAge(int age) {
15         this.age = age;
16     }
17     public int getAge() {
18         return age;
19     }
20     private void log(String msg) {
21         System.out.println(msg);
22     }
23 }

Grape的源码

 1 // Grape仅仅只实现Fruit的函数接口。
 2 public class Grape extends Fruit {
 3     public void grow() {
 4         System.out.println("Grape grow()");
 5     }
 6     public void harvest() {
 7         System.out.println("Grape harvest()");
 8     }
 9     public void plant() {
10         System.out.println("Grape plant()");
11     }
12 }

Strawberry的源码

 1 // Strawberry实现Fruit的函数接口,并且Strawberry中有私有方法log
 2 public class Strawberry extends Fruit {
 3 
 4     public void grow() {
 5         log("Strawberry grow()");
 6     }
 7     public void harvest() {
 8         log("Strawberry harvest()");
 9     }
10     public void plant() {
11         log("Strawberry plant()");
12     }
13     private void log(String msg) {
14         System.out.println(msg);
15     }
16 }

 

4. 客户端测试程序
客户端是"Client"。
Client的源码

 1 public class Client {
 2 
 3     public static void main(String[] args) {
 4         try {
 5             Fruit apple = FruitFactory.newInstance("Apple");
 6             apple.plant();
 7             apple.grow();
 8             apple.harvest();
 9 
10             Fruit grape = FruitFactory.newInstance("Grape");
11             grape.plant();
12             grape.grow();
13             grape.harvest();
14 
15             Fruit strawberry = FruitFactory.newInstance("strawberry");
16             strawberry.plant();
17             strawberry.grow();
18             strawberry.harvest();
19 
20             Fruit error = FruitFactory.newInstance("error");
21             error.plant();
22             error.grow();
23             error.harvest();
24         } catch (BadFruitException e) {
25             e.printStackTrace();
26         }
27     }
28 }

运行结果

Apple plant()
Apple grow()
Apple harvest()
Grape plant()
Grape grow()
Grape harvest()
Strawberry plant()
Strawberry grow()
Strawberry harvest()
BadFruitException: Bad fruit request!
    at FruitFactory.newInstance(FruitFactory.java:17)
    at Client.main(Client.java:21)

结果说明

Client成功创建了Apple, Grape, Strawberry这3个水果对象,并调用了它们的方法;然后创建error时,由于不存在error对应的水果,因此抛出异常。
(01) Fruit,是抽象产品。Fruit中声明了grow(), harvest(), plant()这3个函数接口,它们是水果共用拥有的行为。
(02) Apple, Grape和Strawberry这三个类是具体产品。
      Apple -- 实现Fruit的函数接口,并且Apple中有私有成员age和私有方法log。
      Grape -- 仅仅只实现Fruit的函数接口。
      Strawberry -- 实现Fruit的函数接口,并且Strawberry中有私有方法log
(03) FruitFactory,是工厂类。通过它的newInstance()方法,我们可以获取相应的Fruit对象。若要获取的水果不存在,则抛出BadFruitException异常。BadFruitException是Exception的子类。

 

posted on 2014-02-15 12:30  如果天空不死  阅读(5713)  评论(1编辑  收藏  举报