女媧造人,創造白人,創造黑人,創造黃人。
二)定義
定義一個用於創建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。
三)代碼例子
由四部分組成:1)抽象工廠類;2)具體工廠類;3)抽象產品類;4)具體產品類(可多個);
1)抽象工廠類
/**
* 抽象工廠類
*
* @author levovo
*/
public abstract class AbsFactory {
public abstract <T extends AbsProduct> T createProduct(Class<T> c);
}
2)具體工廠類
/**
* 具體工廠類
*
* @author levovo
*/
public class ConcreteFactory extends AbsFactory {
@Override
public <T extends AbsProduct> T createProduct(Class<T> c) {
AbsProduct product = null;
try {
product = (AbsProduct)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
// 異常處理
}
return (T)product;
}
}
3)抽象產品類
/**
* 抽象產品類
*
* @author levovo
*/
public abstract class AbsProduct {
// 產品類的公共方法
public void method1() {
System.out.println("AbsProduct()->method1()");
}
// 抽象方法
public abstract void method2();
}
4)具體產品類
/**
* 具體產品類1
*
* @author levovo
*/
public class ConcreteProduct1 extends AbsProduct {
@Override
public void method2() {
// 業務邏輯處理
System.out.println("ConcreteProduct1()->method2()");
}
}
/**
* 具體產品類2
*
* @author levovo
*/
public class ConcreteProduct2 extends AbsProduct {
@Override
public void method2() {
// 業務邏輯處理
System.out.println("ConcreteProduct2()->method2()");
}
}
場景使用例子
/**
* 場景使用例子
*
* @author levovo
*/
public class Client {
public static void main(String[] args) {
// 工廠類
AbsFactory factory = new ConcreteFactory();
// 創造產品類1
AbsProduct product1 = factory.createProduct(ConcreteProduct1.class);
product1.method1();
product1.method2();
// 創造產品類2
AbsProduct product2 = factory.createProduct(ConcreteProduct2.class);
product2.method1();
product2.method2();
}
}
四)優點
良好的封裝性,代碼結構清晰,降低模塊間的耦合,擴展性非常優秀,
五)缺點
六)使用場景
1)需要靈活、可擴展的框架時,可以考慮採用工廠方法模式。萬物皆對象,那萬物就皆產品類,例子需要設計一個連接郵件服務器的框架,有三種網絡協議可供選擇:POP3,IMAP,HTTP,我們就可以把這三種連接方法作爲產品類。如此設計,可以做到完美的擴展,如某些郵件服務器提供了WebService接口,很好,我們只要增加一個產品類就可以了。
2)不同品牌的轎車。
3)一個對象擁有很多子類。
七)注意事項
八)擴展
1)縮小爲簡單工廠模式(就是把抽象工廠類去掉,在create***()前面增加static關鍵字)
2)升級爲多個工廠模式
3)替代單例模式
4)延遲初始化,例如:限制某一個產品類的最大實例化數量,可以通過判斷Map中已有的對象數量來實現,這樣的處理是非常有意義的,例子JDBC連接數據庫,都會要求設置一個MaxConnections最大連接數量,該數量就是內存中最大實例化的數量。延遲加載還可以用在對象初始化比較複雜的情況下,例子硬件訪問,涉及多方面的交互,則可以通過延遲加載降低對象的產生和銷燬帶來的複雜性。
九)總結
當設計靈活、可擴展的框架時,考慮使用工廠方法模式,可以完善的擴展。(擴展就是新增一個產品類)