設計模式—工廠方法模式

定義

定義一個用於創建對象的接口,讓子類決定實例化哪個類

使用場景

在任何需要生成複雜對象的地方,都可以使用工廠方法模式。複合對象適合使用工廠模式,用new就可以完成創建的對象無需使用工廠模式。

關鍵點

一個抽象工廠—定義創建對象的接口

抽象工廠的實現類—可以是一個實現或多個實現,用於生產需要的具體對象

一個抽象產品—工廠方法模式所創建的產品的父類

抽象產品的實現類—需要被創建的具體產品

實現

/**
 * 抽象工廠類—定義生產抽象對象的接口
 */
public abstract class AbstractFactory {

    public abstract AbstractProduct createProduct();

}
/**
 * 抽象產品類—工廠模式的抽象接口需要創建返回的類型
 */
public abstract class AbstractProduct {

    /**
     * 抽象產品內的抽象方法
     */
    public abstract void showProductName();

}
/**
 * 抽象工廠的實現類—創建具體需要的產品
 */
public class ProductFactory extends AbstractFactory {

    @Override
    public AbstractProduct createProduct() {
        //根據需要創建具體的產品,這裏我們創建產品A
        return new ProductA();
    }
}
/**
 * 具體的產品A
 */
public class ProductA extends AbstractProduct {

    @Override
    public void showProductName() {
        Log.i("Product:", "A");
    }
}
/**
 * 具體的產品B
 */
public class ProductB extends AbstractProduct {

    @Override
    public void showProductName() {
        Log.i("Product:", "B");
    }
}

使用

AbstractFactory factory = new ProductFactory();
AbstractProduct product = factory.createProduct();
product.showProductName();

輸出

01-01 00:05:58.728 2840-2840/com.example.admin.singleinstancedemo I/Product:: A

當然我們也可以在具體創建產品的工廠類裏面創建B產品。上面這種方式是最常見的需要哪一個產品就生產哪一個。除此之外,我們還可以利用反射的方式去更加簡潔的生產具體的產品對象,修改抽象工廠類和具體工廠類如下:

/**
 * 抽象接口類—定義生產抽象對象的接口
 */
public abstract class AbstractFactory {

    public abstract <T extends AbstractProduct> T  createProduct(Class<T> clz);

}
/**
 * 抽象工廠的實現類—創建具體需要的產品
 */
public class ProductFactory extends AbstractFactory {
    @Override
    public <T extends AbstractProduct> T createProduct(Class<T> clz) {
        AbstractProduct product = null;
        try {
            product = (AbstractProduct) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) product;
    }

}

使用

AbstractFactory factory = new ProductFactory();
AbstractProduct product = factory.createProduct(ProductB.class);
product.showProductName();

輸出結果

01-01 00:26:19.950 16938-16938/com.example.admin.singleinstancedemo I/Product:: B

需要哪一個類的對象就傳入哪一個類的類型即可,這種方式比較簡介、動態,當然我們也可以爲每個具體的產品定義一個具體的工廠類,比如在第一種方式基礎上多增加一個專門用於生產ProductB的工廠

/**
 * 抽象工廠的實現類—創建具體需要的產品B
 */
public class ProductFactoryB extends AbstractFactory {

    @Override
    public AbstractProduct createProduct() {
        return new ProductB();
    }
}

然後需要A的時候使用ProductFactory工廠創建A實例,需要B的時候使用ProductFactoryB工廠創建B實例,各司其職。這樣擁有多個工廠的方式我們稱爲多工廠方法模式。

當只有一個工廠的時候,我們還是爲工廠提供了一個抽象類,是否可以將其簡化掉呢?當然是可以的:

/**
 * 直接提供靜態方法—向外創建對象
 */
public class ProductFactory {

    public static AbstractProduct createProduct(){
        return new ProductA();
    }
}

像這樣的方式又稱之爲簡單工廠模式或靜態工廠模式

小結

工廠方法模式降低了對象之間的耦合度,依賴於抽象的架構,將實例化的任務交由子類去完成,有非常好的擴展性,符合軟件設計原則。

優點:

1.在工廠方法中,用戶只需要知道所要產品的具體工廠,無須關係具體的創建過程,甚至不需要具體產品類的類名。
2.在系統增加新的產品時,我們只需要添加一個具體產品類和對應的實現工廠,無需對原工廠進行任何修改,很好地符合了“開閉原則”。

缺點:

1.每次增加一個產品時,都需要增加一個具體類和對象實現工廠,是的系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章