概要
本章介紹"簡單工廠模式"。內容包括:
簡單工廠模式簡介
簡單工廠模式代碼模型
簡單工廠模式示例
說明:(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的子類。