1.1 簡單工廠(Simple Factory)模式
簡單工廠模式是類別的創建,又稱為靜態工廠方法(Static Factory Methord)模式。簡單工廠模式是由一個工廠物件決定要創造哪一種產品類別的實例。
1.1.1 工廠模式的幾種形態
工廠模式專門負責將大量有共同介面的類別實例化。工廠模式可以動態的決定將哪一個類別實例化,工廠模式有以下幾種形態:
簡單工廠(Simple Factory)模式:又稱靜態工廠方法(Static Factory Methord)模式。
工廠方法(Factory Method)模式:又稱為多態性工廠(Polymorphic Factory)模式或虛擬建構子(Virtual Constructor)模式。
抽象工廠(Abstract Factory)模式:又稱工具箱(Kit或Toolkit)模式。
下圖所示的就是簡單工廠模式的簡略類別圖。
簡單工廠模式,或稱為靜態工廠方法模式,是不同工廠方法模式的一個特殊實現。在Java語言中,通常的工廠方法模式不能透過設計功能的退化給出靜態工廠方法模式。
1.1.2 簡單工廠模式的引進(一般模式)
例如有農場,生產各種水果,有蘋果(Apple)、草莓(Strawberry)、葡萄(Grape);農場的園丁(FruitGardener)要根據客戶的需求,提供相應的水果。以下來看看是如何用簡單工廠模式實現這個過程的,如下圖:
此模式的實作源碼如下:
1.1.2.1 產品介面.patterns.simplefactory.ybgc;
* Created by IntelliJ IDEA.
* FileName:Fruit.java
* User: LavaSoft
* Date: 2006-12-1
* Date: 2006-12-100 著)讀書筆記
* 工廠模式模式--簡單工廠模式--一般模式
* ReadMe: 抽象產品角色:工廠的水果產品介面--水果
*/
public interface Fruit {
/**
* 植牙
*/
void plant(); ();
/**
*/
void harvest();
}
1.1.2.2 產物
/**
* 收穫
*/
private int treeAge;
/**
* Created by IntelliJ IDEA.
* User: LavaSoft
* Date: 著)讀書筆記
* 工廠模式模式--簡單工廠模式--一般模式
* ReadMe: 水果工廠的產品:蘋果
*/ ted .");
}
/**
* 植牙
*/
public void grow() {
System.out.println("Apple
public void harvest() {
System.out.println("Apple has been harvested.");
} return treeAge;
}
/**
*/
public void setTreeAge(int treeAge) {
this.treeAge = treeAge this.treeAge = treeAge
;
1.1.2.3 產品草莓類:Strawberry.java
package com.lavasoft.patterns.simplefactory.ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:Strawberry.java
* User: LavaSoft
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* 對博士著)讀書筆記
* 工廠模式模式--簡單工廠模式--一般模式
* ReadMe: 水果工廠的產品:草莓
*/
public class Strawberry Implements Fruit {/**
* 生長
*/public class Strawberry Implements Fruit { "草莓已收成。");
}
* 收穫
*/
public void plant() {
*
* 植牙
*/
System.out.println(msg);
}
}
softosofthp . patterns.simplefactory.ybgc;
/**
*/
public class Grape 實作Fruit {
private boolean 無籽; // 是否有種子
) v. – {
System.out.println("葡萄種下。");
}
* Created by IntelliJ IDEA.
* FileName:Grape.java * User: LavaSoft
* Date: 2006-12-100 著)閱讀筆記
* ReadMe: 水果工廠的產品:葡萄
*/ ? "葡萄/
public boolean getSeedless() {
return Seedless;
}
less />
* 植牙
o/ }
less />
* 生長
this.seedless = 無種子;
}
/**
* 收穫
*/
System.out.println(msg);
}
}
園林類:55 .lavasoft.patterns .simplefactory.ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:FruitGardener.java
* User: LavaSoft
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* 20博士著)讀書筆記
* 工廠模式模式--簡單工廠模式--一般模式
* ReadMe: 工廠類角色: 水果園丁,生產水果產品
*/
public class FruitGardener {
/**
* 靜態工廠方法
* @param which :特定的產品名稱
* @return 水果物件
*/
public static Fruit factory(String which)
return new Apple();
} else if (which.equalsIgnoreCase("strawberry")) {
Case("grape")) {
return new Grape();
} else {
throw new BadFruitException("Bad fruit request");
FruitException.java
package com.lavasoft.patterns.simplefactory.ybgc;
* Created by IntelliJ IDEA.
* FileName:BadFruitException.java * User: LavaSoft
* Date: 閻宏博士著)讀書筆記
* ReadMe: 工廠的異常處理類
*/
public class BadFruitException extends Exception {
public BadFruitException(String msg) {
1.1.2.7 一般工廠模式的測試類別
package com.lavasoft.patterns.simplefactory.ybgc;
/**
* Created by IntelliJ IDEA.
* FileName:TestApp.java
* User: LavaSoft
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* @著)讀書筆記
* 工廠模式模式--簡單工廠模式--一般模式 * ReadMe: 一般工廠模式的測試類別
*/
/**
* 測試方法
*/
testvate void try {
Fruit f = FruitGardener.factory(fruitName);
adFruitException e) {
System.out.println("對不起!工廠目前不能生產你所要的產品:" + fruitName);
System.out.println(e.getMessage()); //輸出異常堆疊資訊
}
}
/**
* 應用入口方法
*/
public static void main(String args[]) {
t.test("grape ");
t.test("strawberry");
t.test("car"); //此處投擲異常,水果工廠能生產car(轎車)! }
1.1.2.8 測試運行結果
恭喜!生產了一個水果對象:apple
恭喜!生產了一個水果對象:grape
恭喜!生產了一個水果對象:strawberry
對不起!工廠目前不能生產你所要的產品:car
Bad fruit request
com.lavasoft.patterns.simplefactory.ybgc.BadFruitException: Bad fruit request
at com.lavasoft.patterns.simplefactory.ybgc.FruitGardener。 simplefactory.ybgc.TestApp.test(TestApp.java:19)
at com.lavasoft.patterns.simplefactory.ybgc.TestApp.main(TestApp.java:37) at sun.reflect.Native at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at javalang. at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Process finished with exit code 0
1.1.3 簡單工廠模式的一般性結構
總結一下,從上面的簡單工廠模式的實現可以看到,簡單工廠模式需要實作 工廠角色:園藝生水果介面
特定產品:蘋果、葡萄、草莓
工廠異常類
客戶類
簡單工廠模式的一般性結構圖如下:
1.1.4簡單工廠模式的實作
1.1.4.1 使用介面或抽象類別實作多層次的產品結構工廠類別可以有多個靜態的工廠方法,分別用來生產不同的產品物件。 1.1.4.2 多個工廠方法
分別負責創建不同的產品對象,例如java.text.DateFormat類別是其子類別的工廠類,而DateFormat類別就是提供了多個靜態工廠方法。
1.1.4.3 抽象產品角色的省略
如果系統只有一個具體產品角色產品角色的話,那麼就可以省略掉抽象產品角色。省略掉抽象產品角色後的簡略類別圖如下:
下面是一個例子,工廠角色創建特定產品,原始碼如下:
1.1.4.3.1 產品角色:ConcreteProductage .lavasoft.patterns.simplefactory.gchb;/**
* Created by IntelliJ IDEA.
* FileName:ConcreteProduct.java * User: LavaSoft
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
, 2: 8: 宏博士著)讀書筆記
* 工廠模式--簡單工廠模式--工抽合併(工廠角色與抽象產品角色合併)
* ReadMe: 具體產品類,表示單一的一類產品.
*/
public class ConcreteProduct {
public ConcreteProduct() {
age com. lavasoft.patterns.simplefactory.gchb;
/**
* Created by IntelliJ IDEA.
* FileName:Creator.java
* Date: 2006-12-1
* Date: 2006-12-1 * Date: 2006-12-1
* Date: 2006-12-1
*: 著)讀書筆記
* 工廠模式--簡單工廠模式--工抽合併(工廠角色與抽象產品角色合併)
* ReadMe: 特定產品類,與抽象產品角色合併,只生產單一種類產品.
*/
public class Creator {
/**
* 靜態工廠方法
* @return 一個產品
*/
}
1.1.4.3.3 測試類別
package com.lavasoft.patterns.simplefactory.gchb;
/**
* Created by IntelliJ IDEA.
* FileName:TestApp.java
* User: LavaSoft
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* 對博士 著)閱讀筆記
* 工廠模式--簡單工廠模式--工抽合併(工廠角色與抽象產品角色合併)
* ReadMe: 工抽合併測試類別
*/
public class TestApp {
private void test() {
Creator t = Creator.factory();
new TestApp().test();
}
}
1.1.4.4 工廠角色與抽象角色合併
下面是我自己寫的一個實現,源代碼如下:
1.1 .4.4.1 抽象產品類別(同時又是工廠類別)
package com.lavasoft.patterns.simplefactory.cxsl;/*** Created by IntelliJ IDEA.
* FileName:AbsProduct.java * User: LavaSoft
* Date: 2006-12-3
* Date: 2006-12-3
* Date: 2006-12-3
* Date: 博士著)讀書筆記
* 工廠模式--簡單工廠模式--工廠角色與抽象產品角色合併
* ReadMe: 抽象產品類,同時又是工廠類.
*/
public abstract class AbsProduct {) return new Product();
}
}
1.1.4.4.2 特定產品類別
package com.lavasoft.patterns.simplefactory.cxslct; Product(){
}
1.1.4.4.3 測試類
/**
* Created by IntelliJ IDEA.
* FileName:Product.java
* User: LavaSoft
* Date: 2006-12-3
* Date: 2006-12-3
* Date: 2006-12-3
* Date: 2006-12-3
*: 著)閱讀筆記
* 工廠模式--簡單工廠模式--工廠角色與抽象產品角色合併
* ReadMe: 特定產品類
*/
public class TestApp {
Product a = AbsProduct.factory();
System.out.println("成功建立一個產品物件!"); TestApp test = new TestApp(); test.test();
}
1.1.4.4.
1.1.4.4.
Process finished with exit code 0
這個實作很簡單,程式碼就不做詳細解釋了!
1.1.4.5 三個角色全部合併
下面給出一個簡單的實作範例如下:
package com.lavasoft.patterns.simplefactory.shshb;
/**
* Created by IntelliJ IDEA.
* FileName:ConcreteProduct.java
* User: LavaSoft
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* Date: / 宏博士著)讀書筆記
* 工廠模式--簡單工廠模式--三色合一模式
* ReadMe: 抽象產品,產品,工廠類三和一後的具體產品類
*/
public class ConcreteProduct
public ConcreteProduct(){}
/**
* 靜態工廠方法
* @return 特定的產品ConcreteProduct實例
*/ return new ConcreteProduct();
}
}
package com.lavasoft.patterns.simplefactory.sshb;
* Created by IntelliJ IDEA.
* FileName:TestApp.java
* User: LavaSoft
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* Date: 2006-12-1
* 對博士 著)讀書筆記
* 工廠模式--簡單工廠模式--三色合一模式
* ReadMe: 測試方法
ConcreteProduct t=ConcreteProduct.factory();
System.out.println("產品成功生產! ){
new TestApp() .test();
}
}
1.1.4.5.3 測試運算
1.1.4.6 產品物件的循環使用和登記式的工廠方法
這裡在單例模式和多例模式中在討論。簡單工廠模式的優點和缺點
1.1.4.6.1 簡單工廠模式的優點
當產品類別具有複雜的多層等級結構時,工廠類別只有它自己。以不變應萬變,是其缺點。
這個工廠類集中了所有產品創建邏輯,形成了一個無所不知的全能類(也稱上帝類),如果此類出問題了,整個應用都受大影響。
當產品有多個介面時,判斷在什麼條件下創建什麼產品類實例會很困難。
由於簡單工廠模式使用靜態方法作為工廠方法,而靜態方法無法由子類別繼承,因此工廠角色無法形成基於繼承的等級結構。這項缺點會在工廠方法模式中克服。
DateFormat與簡單工廠模式
SAX2庫中的XMLReaderFactory與簡單工廠模式
出一個個的人,這就是簡單工廠模式的應用,類別圖如下: