Java設計模式-工廠方法模式
1. 定義
定義:定義一個用於創建對象的接口,讓子類決定實例化哪一個類。工具方法使一個類的實例化延遲到其子類。
工廠方法模式通用類圖
2. 實例
在我們日常生活中,很多的工廠會用來生產產品,並進行組裝。我們這裏有一個生產機牀(Creator)生產三種不同的產品(ProductA、ProductB、ProductC)。車間工人在生產的時候只需要根據使用情況,輸入需要生產的產品類型(ABC類)就可以獲取到我們需要的產品了。
抽象機牀類
/**
* 抽象機牀類
*/
public abstract class AbstraceCreator {
/**
* 生產產品
* @param c 產品類
* @param <T> 泛型
* @return 根據傳入的產品類創建一個實例
*/
public abstract <T extends Product> T create(Class<T> c);
}
機牀類實現
public class Creator extends AbstraceCreator {
@Override
public <T extends Product> T create(Class<T> c) {
Product product = null;
try {
//根據傳入的類型創建一個產品
product = (T) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T) product;
}
}
產品類
/**
* 產品接口
*/
public interface Product {
//下線組裝方法
void assemble();
}
/**
* 產品A
*/
public class ProductA implements Product{
@Override
public void assemble() {
System.out.println("A產品上線組裝");
}
}
/**
* 產品B
*/
public class ProductB implements Product{
@Override
public void assemble() {
System.out.println("B產品上線組裝");
}
}
/**
* 產品C
*/
public class ProductC implements Product {
@Override
public void assemble() {
System.out.println("C產品上線組裝");
}
}
生產過程模擬
public class Main {
public static void main(String[] args) {
AbstraceCreator creator = new Creator();
Product productA = creator.create(ProductA.class);
Product productB = creator.create(ProductB.class);
Product productC = creator.create(ProductC.class);
productA.assemble();
productB.assemble();
productC.assemble();
}
}
輸出結果
A產品上線組裝
B產品上線組裝
C產品上線組裝
Process finished with exit code 0
3. 應用
3.1 優點
- 具有良好的封裝性,代碼結構清晰。
- 工廠方法模式的拓展性優秀。
- 可以屏蔽產品類。調用者不必關心產品類的具體實現,只需要關心產品類的接口保持不變,系統的上層架構就不會發生改變。
- 工廠方法是典型的解耦框架。
3.2 使用場景
- 替代new方法創建對象
- 需要靈活可拓展的框架時,可以考慮工廠方法模式。
- 使用在異構項目中。
- 使用在測試驅動開發的框架下。
4. 拓展
4.1 簡單工廠模式
如果一個模塊只需要一個工廠類,那麼不必讓一個工廠類去繼承一個抽象類或實現一個接口,只需要使用一個靜態方法就可以實現同樣的功能。
我們參照上面的實例,製作一個新的類圖,來模擬一下簡單工廠模式的實現。
4.2 多個工廠模式
多個工廠模式就是遇到初始化一個對象十分耗費精力(創建流程比較複雜或耗費更多的時間和資源)時,這樣把所有的產品類都放在同一個工廠方法中進行實例化就會是代碼結構不清晰。這時候我們可以使用多個工廠類,每一個工廠類只負責實例化其中一種產品。
我們再一次修改類圖,得到多個工廠模式的類圖。
4.3 替代單例
我們上一篇博客中介紹了單例的實現方式,一個單例的通用類圖爲:
在使用工廠方法模式時,我們也可以通過反射的機制來創建單例
/**
* 工廠模式實現單例
*/
public class SingletonFactory{
private static Singleton singleton;
static {
try{
Class clazz = Class.forName(Singletong.class.getName());
//獲取無參構造函數
Constructor constructor = clazz.getDeclaredConstructor();
//設置無參構造可以訪問
constructor.setAccessible(true);
//通過放射創建一個實例
singleton = (Singleton) constructor.newInstance();
} catch (Exception e){
e.printStackTrace();
}
}
public static Singleton getInstance(){
return singleton;
}
}