2015-09-03 41 views
3

問題是關於GoF解釋工廠模式。FactoryPattern構造物體

我有一個Tree<SqlRestriction>其中

public interface SqlRestriction{ 
    public String getSql(); 
} 

現在,我需要創建一個名爲集裝箱接口的對象:

public interface Container{ 
    //methods 
} 

下面是其實現的一個:

public class SimpleSqlListContainer implements Container{ 
    private Integer rate; 
    private String relation; 
    //GET, SET, CTORs, other methods 
} 

所以,我傾向於將對象創作包裝到工廠

public class ContainerFactory{ 
    public Container create(Tree<SqlRestriction> restrinctions){ 
     //impl 
    } 
} 

實際的創建以及正確初始化要通過遍歷作爲參數傳遞的Tree進行。

問題:如果我初始化它會被認爲是好是被工廠方法中創建的對象。或者它可能會誤導其他開發者?因此,在工廠方法中,我們是否應該避免任何形式的初始化,並只執行對象創建,將初始化留給客戶端。

+3

目前還不清楚構建和初始化之間有什麼不同。兩者通常應由構造函數完成。一般來說,構建的對象應該可以使用。最重要的是如果文件:明確工廠做什麼並返回。 –

+0

@JBNizet但是在JavaBean中,我們通常使用deafult構造函數,它通常具有空的body和getter/setter? –

+0

並非所有東西都應該是JavaBean。即使JavaBean具有無參數構造函數,它也應該是(並且通常)可用而不必調用任何setter。 –

回答

1

工廠模式的關注點是根據提供的參數做出決定返回什麼類型的對象。它封裝了這個邏輯。如果Container類的其他實現適用於特定類型的SqlRestriction,那麼工廠將爲您做出該決定。

初始化Container的問題似乎屬於Container本身。因爲它會知道它是如何遍歷樹的,所以它被傳遞以包含對象。

2

GoF模式沒有提到對象初始化(我已經重讀了這一章來確認)。該模式的唯一目的是隱藏工廠實現中的類型選擇。

這就是說,如果你建立一批具有一定類型的對象,和他們每個人都有相同的初始化序列,例如:

public IFoo createFoo(){ 
    ConcreteFoo foo = new ConcreteFoo(); 
    foo.setField1("a"); 
    foo.setField2("b"); 
    .... 
    foo.setFieldN("z"); 
    return foo; 
} 

是在代碼中多次重複任何初始化序列應封裝在某處以避免代碼重複。只有當它應用於該類的每個可能的實例時,這個初始化才能進入構造器。我在談論默認值。現在,如果初始化序列不適用於類的每個實例,而是爲某個特定目的而創建的,則應從構造函數中取出。

只要初始化用例在您的應用程序中足夠常見,那麼工廠實現將是一個很好的選擇。工廠接口應該是這樣的:

public interface IFooFactory { 
    public IFoo createFooForThis(); 
    public IFoo createFooForThat(); 

    ... 

} 

事實上,如果我們需要調用屬於ConcreteFoo類是不存在IFoo接口foo的情況下制定者,這是唯一的地方,你可以這樣做,因爲客戶端代碼不能調用IFoo接口以外的方法。