Java設計模式3:工廠方法模式

五月的倉頡發表於2015-10-23

工廠方法模式

工廠方法模式是類的建立模式。工廠方法模式的用意是定義一個建立產品物件的工廠介面,將實際建立工廠推遲到子類中

 

工廠方法模式

工廠方法模式是對簡單工廠模式進一步抽象的結果。

假如是不使用反射的工廠方法模式,那麼所有的if...

else if...else都放在工廠類中,勢必造成工廠類的無限臃腫

這時候就需要工廠方法模式來處理這個問題了。工廠方法模式中,核心的工廠類不再負責所有物件的建立,而是將具體的建立工作交給子類去做。這個類則搖身一變變成了一個抽象工廠角色,僅僅負責給出具體工廠子類必須實現的介面。

這一步的改進,使得系統可以在不修改具體工廠角色的情況下引入新的產品。

 

工廠方法模式結構

使用工廠方法模式的系統涉及到以下角色:

1、抽象工廠角色

擔任這個角色的是工廠方法模式的核心,任何在模式中建立物件的工廠類必須實現這個介面

2、具體工廠角色

擔任這個角色的是實現了工廠介面的具體Java類,具體工廠角色與業務密切相關,並且隨著使用者的呼叫以建立匯出類

3、抽象匯出角色

工廠方法模式所建立的物件的超類

4、具體匯出角色

這個角色實現了抽象匯出角色所宣告的介面,工廠方法模式所建立的每一個物件都是某個具體角色匯出角色的例項

 

工廠方法模式的示例

有一個抽象工廠,匯出檔案的工廠:

public interface ExportFactory
{
    public ExportFile factory(String type);
}

它有兩個實現類,分別是匯出HTML檔案的工廠和匯出PDF檔案的工廠:

public class ExportHtmlFactory implements ExportFactory
{
    public ExportFile factory(String type)
    {
        if ("standard".equals(type))
        {
            return new ExportStandardHtmlFile();
        }
        else if ("financial".equals(type))
        {
            return new ExportFinancialHtmlFile();
        }
        return null;
    }
}
public class ExportPdfFactory implements ExportFactory
{
    public ExportFile factory(String type)
    {
        if ("standard".equals(type))
        {
            return new ExportStandardPdfFile();
        }
        else if ("financial".equals(type))
        {
            return new ExportFinancialPdfFile();
        }
        return null;
    }
}

抽象產品角色,一個匯出檔案:

public interface ExportFile
{
    public boolean export(String data);
}

具體產品角色:

public class ExportFinancialHtmlFile implements ExportFile
{
    public boolean export(String data)
    {
        System.out.println("匯出財務版HTML檔案");
        return false;
    }
}
public class ExportFinancialPdfFile implements ExportFile
{
    public boolean export(String data)
    {
        System.out.println("匯出財務版PDF檔案");
        return true;
    }
}
public class ExportStandardHtmlFile implements ExportFile
{
    public boolean export(String data)
    {
        System.out.println("匯出標準HTML檔案");
        return true;
    }
}
public class ExportStandardPdfFile implements ExportFile
{
    public boolean export(String data)
    {
        System.out.println("匯出標準PDF檔案");
        return true;
    }
}

模擬客戶端呼叫,例項化出一個具體的工廠角色,根據傳入的引數返回不同的產品角色:

public static void main(String[] args)
{
    String data = "";
    ExportFactory exportFactory = new ExportHtmlFactory();
    ExportFile ef = exportFactory.factory("financial");
    ef.export(data);
}

返回結果為:

匯出財務版HTML檔案

當然,也可以修改程式碼,看自己喜好,例項化出不同的子類並且呼叫export方法列印。

 

工廠方法模式在Java中的應用及解讀

拿ThreadFactory舉個例子,顧名思義,這是一個生產執行緒的介面:

public interface ThreadFactory {

    /**
     * Constructs a new {@code Thread}.  Implementations may also initialize
     * priority, name, daemon status, {@code ThreadGroup}, etc.
     *
     * @param r a runnable to be executed by new thread instance
     * @return constructed thread, or {@code null} if the request to
     *         create a thread is rejected
     */
    Thread newThread(Runnable r);
}

具體的執行緒工廠可以implements這個介面並實現newThread(Runnable r)方法,來生產具體執行緒工廠想要生產的執行緒。JDK在Executors給開發者提供了一個靜態內部類DefaultThreadFactory,當然開發者也可以自行實現這個介面,寫自定義的執行緒工廠。

 

總結

對於系統的設計應該足夠靈活並儘可能降低程式碼之間的耦合度,當修改或增加一個新的功能時,使得使用者儘可能修改少的地方即可。假如設計不夠靈活,將無法面對多變的需求,可能一個極小的需求變更,都會使程式碼結構發生改變,並導致其他使用的人都要修改他們的程式碼。牽一髮而動全身,系統日後的維護將變得艱難。

 

相關文章