2009-02-03 25 views
1

我想開發一個process()方法。該方法以數據類的形式獲取一些數據,並對其進行處理。數據類是相似的,但略有不同。面向對象的方法設計選項

例如,我們有以下幾類數據processDataObject_A,processDataObject_B和processDataObject_C。

是更好過載方法:

void process(processDataObject_A data) 
{ 
//Process processDataObject_A here 
} 

void process(processDataObject_B data) 
{ 
//Process processDataObject_B here 
} 

void process(processDataObject_C data) 
{ 
//Process processDataObject_C here 
} 

OR具有具體的數據類來擴展一些抽象數據類,並傳遞到處理方法,然後讓該方法檢查類型並據此採取行動:

void process(AbstractProcessDataObject data) 
{ 
//Check for type here and do something 
} 

或者有沒有更好的方法來解決它?如果這是Web方法,方法會改變嗎?

在此先感謝

回答

8

我會去的:

process (data) { 
    data.doProcessing(); 
} 
+0

它本身並沒有表明它是如何工作的 - 正在使用什麼方法等等;如果doProcessing()是虛擬的(多態),過程(數據)方法的重點是什麼?直接調用它。 – 2009-02-03 12:24:53

+0

+1:將進程()作爲多態方法委託給類。 – 2009-02-03 12:30:28

0

如何多態性上AbstractProcessDataObject - 即一個虛擬的方法?如果這不合適(分離關注等),那麼超載似乎更可取。

Re web-methods;非常不同:無論是多態還是超載都得不到很好的支持(至少不是基本配置文件)。檢測選項「在此檢查類型並執行操作」可能是最佳路線。或者爲每種類型使用不同的命名方法。


每個請求:

abstract class SomeBase { // think: AbstractProcessDataObject 
    public abstract void Process(); 
} 
class Foo : SomeBase { 
    public override void Process() { /* do A */ } 
} 
class Bar : SomeBase { 
    public override void Process() { /* do B */ } 
} 
SomeBase obj = new Foo(); 
obj.Process(); 
1

,你的方法返回void使我相信,你可以有你的責任轉身的事實。我認爲考慮這個可能會更好,因爲讓每個類都實現一個接口IProcessable,該接口定義了Process方法。然後每個班級都會知道如何操作自己的數據。我認爲,這比擁有一個處理每個對象內部數據的類更不耦合。假設所有這些類都是從相同的基類派生出來的,那麼您可以放置​​在基類中共享的處理算法片段。

這與您可能有多種算法對相同數據進行操作的情況稍有不同。如果你需要這種功能,那麼你可能仍然想要實現這個接口,但是Process方法需要一個策略類型參數,並且使用一個工廠來根據它的類型創建一個合適的策略。您最終會以這種方式爲每個支持的算法和數據類對創建一個策略類,但您可以保持代碼解耦。如果算法相當複雜,我可能只會這樣做,因此分離代碼使其更具可讀性。如果只有幾行不同,則在策略類型上使用switch語句可能就足夠了。

關於網絡方法,我想我會有不同的類每個簽名。如果方法使用各種類型的具體類來正確地獲取數據,那麼它就會更容易,因此它知道如何正確地序列化/反序列化它。當然,在後端web方法可以使用上述方法。

public interface IProcessable 
{ 
    public void Process() {....} 
} 

public abstract class ProcessableBase : IProcessable 
{ 
    public virtual void Process() 
    { 
     ... standard processing code... 
    } 
} 

public class FooProcessable : ProcessableBase 
{ 
    public override void Process() 
    { 
     base.Process(); 
     ... specific processing code 
    } 
} 

... 

IProcessable foo = new FooProcessable(); 
foo.Process(); 

實施基於策略的機制稍微複雜一點。

Web界面,使用數據訪問對象

[WebService] 
public class ProcessingWebService 
{ 
    public void ProcessFoo(FooDataObject foo) 
    { 
     // you'd need a constructor to convert the DAO 
     // to a Processable object. 
     IProcessable fooProc = new FooProcessable(foo); 
     fooProc.Process(); 
    } 

} 
1

我第二馬爾科的設計。 想象一下,您需要添加另一種類型的數據結構和流程邏輯,如processDataObject_D。使用您的第一個建議的解決方案(方法重載),您將不得不通過添加其他方法來修改該類。用你的第二個建議的解決方案,你將不得不在類型檢查和執行語句中添加另一個條件。兩者都需要你修改現有的代碼。 Marko的解決方案是通過利用多態性來避免修改現有代碼。您不必編碼if-else類型的檢查。只要新類繼承相同的超類,它就允許您添加新的數據結構和處理邏輯而不修改現有代碼

學習策略模式的設計模式會給你充分的理論上的理解你所面臨的問題。 O'Reilly編寫的「Head First Design Pattern」是我所瞭解的最好的介紹。