設計模式01之 簡單工廠模式(創建模式)


 

概要

本章介紹"簡單工廠模式"。內容包括:
簡單工廠模式簡介
簡單工廠模式代碼模型
簡單工廠模式示例

說明:(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的子類。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM