2010-05-25 73 views
1

我正在研究Guice,最近我一直在閱讀它的文檔。對這個工廠感到困惑,因爲它看起來不像一個抽象工廠或工廠方法

閱讀motivation部分我不明白工廠的一部分,爲什麼他們這樣命名。對我來說,這個工廠只是實現類的包裝,他們希望它在調用getInstance()之後返回。

public class CreditCardProcessorFactory { 

    private static CreditCardProcessor instance; 

    public static void setInstance(CreditCardProcessor creditCardProcessor) { 
    instance = creditCardProcessor; 
    } 

    public static CreditCardProcessor getInstance() { 
    if (instance == null) { 
     throw new IllegalStateException("CreditCardProcessorFactory not initialized. " 
      + "Did you forget to call CreditCardProcessor.setInstance() ?"); 
    } 

    return instance; 
    } 
} 

他們爲什麼把它叫做工廠,以及如果它既不是一個抽象的工廠,也不是工廠方法(至少他們最初是由GoF的定義)?或者我錯過了什麼?

謝謝。

編輯:如果有人想出一個更好的標題,我會很樂意改變它。

回答

3

我是該文檔的作者。我將其稱爲工廠,以便與JDK類(如DocumentBuilderFactory和TransformerFactory)保持一致。例子以前版本返回的默認實現,如果setInstance中()從未被調用:

public static CreditCardProcessor getInstance() { 
    if (instance == null) { 
     return new SquareCreditCardProcessor(); 
    } 
    return instance; 
    } 

我改變了它,以避免從工廠到其執行編譯時依賴。該類具有setInstance(),因爲它比JDK用於在運行時選擇實現的系統屬性更簡單。

由於我們試圖激發依賴注入,顯示一個功能齊全的工廠可能看起來不公平,即使這意味着不忠於原始的GoF模式。

+0

嗯,我真的不知道Guice的工廠如何與DocumentBuilderFactory保持一致,例如,其中有一個工廠方法,但沒有像Guice案例那樣的setInstance。 DocumentBuilderFactory似乎更符合我認爲的GoF模式。但我想你的帖子最能回答我的問題。 – Pin 2010-05-25 19:52:17

+0

好吧,我可以看到有人和Guice一起工作,回想起Guice可以稱之爲工廠之前的那些日子。 Jesse,你爲什麼選擇一個單例子呢?它只是混淆了每個人。 – nes1983 2010-05-27 13:41:41

+0

我修復了文檔! – 2010-05-28 15:30:49

2

這可能只是一個簡化。 Java有一堆工廠類,它們是這樣使用的:

Foo newFoo = FooFactory.getInstance().makeFoo(); 

......其實,它與本例中的內容大致相同。是的,Guice示例使用靜態方法而不是單線方法的方法,但我們已經知道singletons are little more than a very roundabout way of making static methods and fields。我認爲他們只是做了一些快速的事情來展示代碼的糟糕程度,而且他們並不在意遵守GoF模式規範。

+0

在你提到的那些工廠類中,你是否必須先調用setInstance(FooImpl)?在Guice的例子中,'creditCardProcessor'被注入。 – Pin 2010-05-25 14:46:08

+0

我現在唯一能想到的類是'DocumentBuilderFactory',它具有稍微更先進的方式來選擇'newInstance()'(幾乎* * getInstance()';)返回:http:/ /java.sun.com/javase/6/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#newInstance%28%29 – gustafc 2010-05-25 19:16:06

0

雅但沒有任何實例化(私人構造函數)的防止,它也不完全遵循單例模式。

讓它在這裏完整的代碼... :)

3

我已經使用了類似的模式,其中的代碼可以被賦予不同的類取決於它的上下文做一些事情。例如,如果CreditCardProcessor是一個接口或抽象類,那麼高級代碼想要通過創建它並將其傳遞給CreditCardProcessorFactory來設置要使用的實現。使用代碼只是獲得一個CreditCardProcessor而不關心它是什麼實現。

這與工廠模式有些相似,因爲您獲得的是CreditCardProcessor而不關心您擁有哪種實現;你只是沒有傳遞任何參數給工廠方法(在這種情況下,命名不好的getInstance())。你得到的實現取決於其他代碼的設置,而不是你指定的參數。在這種情況下,我甚至可以打電話給我實施工廠的班級。

getInstance()和setInstance()是錯誤的名稱,因爲它們使您想到Singleton。我會去getCreditCardProcessor和setCreditCardProcessor。