2017-06-22 106 views
0

我學習設計Patters和我有哪裏我不知道這將是一個更好的做法的情況:工廠模式或擴展方法?

我有一個類「類別」其中有幾個字段:姓名,2種網址,相關名單對象。有一種方法'toHtml()',它基本上從該類的實例中生成一些HTML。

有4種不同類型的「類別」具有完全相同的字段,但'toHtml()'方法應該給每個類別提供不同的結果。

我不確定是否應該傳遞一個參數「type」和一系列ifs/switch語句來生成不同的html,或者我應該創建一個Category類的抽象類並創建幾個覆蓋toHtml()方法的子類,那麼使用CategoryFactory類來生成它們?在這兩種情況下,我需要傳遞'type'參數。

我試着考慮'關閉修改,打開擴展'OOP規則。但在這種情況下,如果我想添加'第五'類別類型,這會生成不同的html - 對於第一個解決方案,我只需要修改toHtml方法(如果再添加一個),則需要創建附加的子類AND修改CategoryFactory類。

什麼會更好的做法?當我有類似的困境時,我是否應該遵循任何額外的規則?

+0

我會使類別類抽象,擴展它爲每個類型,並讓你的每個類型自己toHTML()。我建議不要在抽象類中創建一個默認的toHTML(),並強制類實現它們自己的類。 –

+0

非常感謝你@RAZ_Muh_Taz的建議! – x1r15

回答

0

首先,我相信你指的是工廠方法,而不是抽象工廠模式。

主要區別在於,前者爲單個產品定義通用模板,而後者則爲產品系列定義模板。欲瞭解更多信息,你可以看看here

對於您的情況,您希望爲Category定義模板。有了這個前提,這裏是你的類組會是什麼樣子:

abstract class Category { 
    public void doSomething() { 
     Foo f = makeFoo(); 
     f.whatever(); 
    } 

    abstract void toHtml(); 
} 

class Category1 extends Category { 
    public override void toHtml() { 
     ... // do something here 
    } 
} 

class Category2 extends Category { 
    public override void toHtml() { 
     ... // do something else here 
    } 
} 

這是事實,這肯定有很多的代碼,並可以很容易地這樣表示:

class Category { 
    public void toHtml(Integer param) { 
     if(param == 1) { // do something for Category1 
     } 
     else { // do something for Category2 
     } 
    } 

在這一天結束,它確實是一個設計決定。有一些因素可以考慮。這將會是一個不斷變化的課堂嗎?這是要宣佈全球客戶使用?你希望客戶如何使用它?

在這一點上更容易的事情是採取阻力最小的路徑。擁有一個類來爲所有類別提供服務肯定會減少代碼,而在Salesforce中,減少代碼總是更好的選擇。但請考慮這一點:將您的功能抽象爲單獨的類使得更易維護的代碼。你可能會發現編寫一個類和一堵if語句更容易,但明天當你不在身邊時,出現嚴重故障並且有人必須仔細查看代碼才能找出究竟哪個if引起了問題,他們會詛咒你。

請記住,繼承是一個全或無的機制。如果您有一些常用功能,您可能會發現它特別有用,在這種情況下,您可以選擇將其抽象到父類中,並讓您的孩子處理這些細節。

+0

非常感謝您的全面回答。你一直很有幫助。 :) – x1r15

+0

@ x1r15:來自一個SF背景,我知道你正在經歷什麼,因爲我以前曾經處於同樣的情況。在這一天結束的時候,我決定咬下子彈並寫下那些額外的課程,並且從那以後它並沒有傷害到我。 :)乾杯。 –

0

如果您創建Category的子類並重寫toHtml()方法,爲什麼您需要有工廠模式。如果您使用引用調用運行時解析類的toHtml()方法,將會被調用。這意味着如果你添加一個新的Category子類,那麼你重寫toHtml()方法,它應該可以正常工作。

+0

不同的子類將在不同的地方實例化。因此,我儘量避免直接創建它們,因爲這意味着在需要創建對象的每個地方都會做出「相同的決定」。 – x1r15