2010-03-04 46 views
7

Factory Method pattern(不要與工廠或抽象工廠模式混淆)是否違反了Open/Closed principle工廠方法模式是否違反開放/關閉原則?

更新: 爲了澄清,我指的是具體類具有靜態工廠方法的場景。例如(這是從維基百科頁面上FMP):

class Complex 
{ 
    public static Complex fromCartesian(double real, double imag) { 
     return new Complex(real, imag); 
    } 

    public static Complex fromPolar(double modulus, double angle) { 
     return new Complex(modulus * cos(angle), modulus * sin(angle)); 
    } 

    private Complex(double a, double b) { 
     //... 
    } 
} 

不私有構造函數阻止類被子類,即延長?

是不是要修改這個類來支持新的工廠方法?例如,如果班級最初只來自笛卡兒,後來需要來自太陽隊,那麼班級是不是必須修改才能支持這一點?

這兩個都不違反開放/關閉?

+2

我想在回答之前知道您對此的看法。你的回答會讓我覺得你正在尋找答案。否則,就像你正在將你的工作外包給SO一樣。 – 2010-03-04 17:13:06

+0

對不起,正計劃添加一條評論,但因工作而偏離了原路。 :) 我在想這確實違反了它。如果我錯了,請糾正我,但FMP指定一個私有構造函數,而私有構造函數禁止擴展。另外,是否不需要修改類以支持其他實現?我正在考慮一個類有靜態工廠方法的情況。也許這只是FMP的一種味道? – 2010-03-04 17:55:14

+0

如果它是一個子類,那麼你可以覆蓋該方法或使用super()(假設Java)。你最好不要使用靜態方法,並且有一個方法需要使用switch語句或通過讀取提供的配置文件來獲取參數。 – 2010-03-04 19:20:39

回答

3

不,它根本沒有違反開放/封閉原則。

打開/關閉意味着您可以在不修改已存在的代碼的情況下修改系統的工作方式。您可以擴展代碼並以不同的方式使用代碼,但舊代碼仍然完好無損,無需重新測試。

工廠方法模式將根據指定的參數創建不同類型的對象。如果正確完成,工廠方法在開放/關閉原則下效果良好。但是,如果您創建一個新類並希望Factory Method創建該類型的新對象,則必須更改Factory Method。

儘管如果你有某種類型的配置文件或者是由Factory Method讀入的那種配置文件,那麼你不必改變Factory Method ...只是配置文件,然後指定什麼對象將由工廠方法創建。

2

沒有。從您的維基百科鏈接:

軟件實體(類,模塊,函數等)應該對擴展開放,對修改關閉

重寫工廠方法是擴展。你正在創建一個新班級。你不要改變現有的類。您必須替換(通過希望配置您的IoC容器)原始子類。

5

工廠模式本質上不是違規者OCP

取決於如何進一步行使Complex

如果Complex需要支持生產新型Complex對象,而你選擇加入新fromX方法添加到支持他們修改Complex,那麼這意味着Complex成爲OCP因爲Complex必須的違法行爲重開進行修改:

class Complex 
{ 
    public static Complex fromCartesian(double real, double imag) { 
     return new Complex(real, imag); 
    } 

    public static Complex fromPolar(double modulus, double angle) { 
     return new Complex(modulus * cos(angle), modulus * sin(angle)); 
    } 

    //class opened for modification 
    public static Complex fromOtherMeans(String x , String y) { 
     return new Complex(x, y); 
    } 
} 

你可以向下推,這個問題用某種形式的文本文件或屬性文件,以免除不得不改變Java類的自己,但它並不妨礙你不必在ord中的解決方案的這個區域寫入額外的邏輯呃支持Complex的新類型。

根據您設計中Complex的用法(各種類型有何不同?您如何使用它們?),還有一些可能適用的替代選項。

一個這樣的OCP友好的替代方法是子類Complex提供額外的工廠方法。子類是Complex如何擴展但未修改的最簡單說明。

另一個OCP在這種情況下友好的替代ComplexDecorator pattern。能夠創建Complex的新變體的持續修飾Complex尊重OCP,因爲Complex未被修改,但通過用新功能包裝來擴展。

第三個替代方案可能是改變Complex的結構,使其計算由組合提供。這將使您有機會使用Strategy pattern區分Complex的不同行爲。

有關工廠模式的事情是它有助於上下文代碼方面OCP。有人可能會採用上述技術之一,以保留其Factory類的OCP的右側,但您的同事可能會看一看對象圖,質疑在單個工廠中擁有對象圖的智慧,並將其簡化爲一個Factory,這會將您帶回第一個示例。

在這種情況下,不要試圖彎曲工廠模式的實施以遵守SOLID原則,請考慮爲什麼您使用的所有