2010-08-10 53 views
4

我們剛剛和大學討論過以下可以接受的oop與否的樣式。oop:在具體情況下的構成或繼承

我們還有一類,它有一個公共職能,並要求在構造讀者:

public class Converter 
{ 
    private readonly IReader _reader; 

    public Converter(IReader reader) 
    { 
     _reader = reader; 
    } 

    public byte[] Convert(...params...) 
    { 
     return something; 
    } 
} 

我們有Reader1和Reader2這兩者實施的iReader。

我想設置兩個管理器:Converter1和Converter2,提供相同的公共Convert()函數,但Converter1將使用Reader1,而Converter2將使用Reader2。

對我來說,最簡單的解決方案是從轉換器繼承以及適當的閱讀器初始化:

public class Converter1 : Converter 
{ 
    public Converter1():base(new Reader1()) 
    {} 
} 
public class Converter2 : Converter 
{ 
    public Converter2():base(new Reader2()) 
    {} 
} 

我的大學說,這Converter1和Converter2是經理,和繼承不應該用於管理人員,而不是我們應該在這裏應用作文。但從我的角度來看,組合只會導致特定轉換器類中的額外代碼。

那麼,請問您可否請指教,是否可以在執行經理時使用繼承? 謝謝

回答

3

你爲什麼繼承?

根據您提供的示例,除了確保Converter1/Converter2強制執行特定類型的讀取器之外,您除了基類之外沒有其他任何操作。

在我看來,你的同事是對的。你應該做的是實現一個工廠方法,它將爲你創建和填充正確配置的Converter。

public static class ConverterFactory { 
    public static CreateConverter1() { 
     return new Converter(new Reader1()); 
    } 
    public static CreateConverter2() { 
     return new Converter(new Reader2()); 
    } 
} 

... 
Converter x = ConverterFactory.CreateConverter1(); 
2

在我看來,這是對繼承的濫用。您並非專門針對轉換器的行爲 - 您只是專門製造構造

特別的,你可以很容易地與靜態方法的靜態類來執行這種結構:

public static class Converters 
{ 
    public static Converter CreateConverter1() 
    { 
     return new Converter(new Reader1()); 
    } 

    public static Converter CreateConverter2() 
    { 
     return new Converter(new Reader2()); 
    } 
} 

這甚至可能是正常Converter類中的靜態方法,當然。

事實上,這失去了功能暗示我的繼承是一個錯誤。

然後,我經常懷疑繼承。恰當地設計繼承意味着找出擴展點,記錄它們應該如何表現 - 這是在給予調用者足夠的信息以預測一致行爲之間的平衡行爲,並且賦予執行者足夠的空間以有用的方式改變行爲。在這裏,你沒有做任何這樣的事 - 你只是改變傳遞給構造函數的讀者。

+0

靜態方法並非如此,因爲我需要將這些Converter1/Conerter2推入其他類的構造函數中,並且調用靜態方法不會是單元可測試的。 將工廠注入消費者類也太多了。 我絕對需要兩個經理類,但你可能是對的,繼承不是這裏最好的東西.. :) – Shaddix 2010-08-10 11:13:14

0

要麼使用繼承(像你這樣的建議),或只使用一個轉換器類將與多態的iReader工作。