**定義:**Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. 也就是說,我們定義一個接口用於創建對象,但讓子類去決定實例化哪一個對象。換句話說,就是工廠方法將對象的實例化工作轉交給了它的子類,而工廠類本身只定義對象實例化規範。
示例簡介:通過工廠類接口,創建多個不同的產品類實例。
類圖:
其中Product爲產品抽象類,其具體產品類ProductA與ProductB爲其子類;ProductFactory爲抽象工廠接口,提供了創建產品對象的方法,ConcreteProductFactory類爲該接口的實現類。通過傳入對應Class對象,調用createProduct()方法返回對應產品實例對象。其具體代碼如下:
Product.java
/**
* Created by Song on 2016/8/31.
* 抽象產品類
*/
public abstract class Product {
public abstract void introduction();
}
ProductA.java
/**
* Created by Song on 2016/8/31.
* 具體產品類
*/
public class ProductA extends Product {
@Override
public void introduction() {
System.out.println("這是產品A");
}
}
ProductB.java
/**
* Created by Song on 2016/8/31.
* 具體產品類
*/
public class ProductB extends Product {
@Override
public void introduction() {
System.out.println("這是產品B");
}
}
ProductFactory.java
/**
* Created by Song on 2016/8/31.
* 工廠接口
*/
public interface ProductFactory {
//創建實例接口
public <T extends Product> T createProduct(Class<T> c);
}
ConcreteProductFactory.java
/**
* Created by Song on 2016/8/31.
* 工廠接口實現類
*/
public class ConcreteProductFactory implements ProductFactory {
public <T extends Product> T createProduct(Class<T> c) {
Product product;
try{
product = (Product) Class.forName(c.getName()).newInstance();
}catch (Exception e){
return null;
}
return (T)product;
}
}
測試代碼
/**
* Created by Song on 2016/8/31.
*/
public class Main {
public static void main(String [] args){
Product product;
//創建產品工廠實例
ProductFactory factory = new ConcreteProductFactory();
//獲取產品A實例
product = factory.createProduct(ProductA.class);
product.introduction();
//獲取產品B實例
product = factory.createProduct(ProductB.class);
product.introduction();
}
}
結果:
優點:工程方法模式擁有良好的封裝性,代碼結構很清晰,獲取產品對象只需要知道類名就夠了,不用知道其創建過程。另外,工廠方法模式擁有良好的擴展性,只需適當增加產品類與修改工廠類或新增工廠類,就能夠適應新的環境。