2009-02-01 63 views
2

這可能是顯示通過我的幼稚,但無論如何...通用接口作爲方法參數,看到領域

我有一個通用的接口,它定義了一組不同實現標準方法(不同的方式實現)。

我將接口作爲參數傳遞給方法,該方法負責持久化數據庫。例如。我有一些實現稱爲bug,事件等,從通用接口(稱爲IEntry)定義。這些concerete實現也使用IEnumerable

因爲錯誤是不同的事件,有不同的領域。當我將接口作爲參數傳遞給方法時,有什麼方法可以推斷這種類型嗎?所以如果我傳入Bug對象,我可以使用它的字段,這些字段與事件中的字段不同。這些字段對於數據庫的持久性很有用。我假設沒有,因爲沒有辦法知道通過什麼類型(顯然),但我知道這裏的人有更多的智慧。在那種情況下,是否有更好的做事方式?由於相似性,我想堅持接口。

編輯:我想另一種方法是利用一些流量控制來生成在運行中的SQL語句,然後作爲參數傳遞它。

感謝

回答

3

約四周傳遞對象和接口的事情是,你真的不應該與實際類型而言,只要它繼承/實現了特定的基類/接口你有興趣

因此,將邏輯構建到該方法中以發現它是一個錯誤,然後訪問僅存在於錯誤中的東西,這基本上不是OOP方式,儘管它可能是您的特例中的「最佳」方式。但是,我會,但是,建議反對它,而是嘗試建立一個適當的OOP與多態性的方式來處理差異,而不是作爲特殊情況構建到方法。

你提到持久性,這種方法負責存儲數據的地方?也許你可以將收集信息的部分從存儲信息的部分中分離出來,這樣你可以要求對象本身爲你提供所有相關的信息,這些信息可能因類而異。

0

持久性事件只是一個方法在一個類中上傳細節到數據庫。

我想我可以寫一個抽象類與持久性要求的功能,並可能基於它的參數工作。我可以在我的每個接口實現中使用它。因爲更新數據庫的方式將會發生(幾乎相同,但sql查詢中的幾個字改變),所以我可以根據方法參數生成它。

3

糟糕的設計(我認爲在這個問題被描述):

public interface IEntry 
{ 
    string Description { get; set; } 
} 
public class Bug : IEntry 
{ 
    public int ID { get; set; } 
    public string Description { get; set; } 
    public string UserName { get; set; } 
} 
public class Incident : IEntry 
{ 
    public Guid ID { get; set; } 
    public string Description { get; set; } 
} 

public class Persister 
{ 
    public void Save(IEnumerable<IEntry> values) 
    { 
     foreach (IEntry value in values) { Save(value); } 
    } 

    public void Save(IEntry value) 
    { 
     if (value is Bug) { /* Bug save logic */ } 
     else if (value is Incident) { /* Incident save logic */ } 
    } 
} 

改進設計(智能實體法):

public interface IEntry 
{ 
    string Description { get; set; } 
    void Save(IPersister gateway); 
} 

public class Bug : IEntry 
{ 
    public int ID { get; set; } 
    public string Description { get; set; } 
    public string UserName { get; set; } 

    public void Save(IPersister gateway) 
    { 
     gateway.SaveBug(this); 
    } 
} 

public class Incident : IEntry 
{ 
    public Guid ID { get; set; } 
    public string Description { get; set; } 

    public void Save(IPersister gateway) 
    { 
     gateway.SaveIncident(this); 
    } 
} 

public interface IPersister 
{ 
    void SaveBug(Bug value); 
    void SaveIncident(Incident value); 
} 

public class Persister : IPersister 
{ 
    public void Save(IEnumerable<IEntry> values) 
    { 
     foreach (IEntry value in values) { Save(value); } 
    } 

    public void Save(IEntry value) 
    { 
     value.Save(this); 
    } 

    public void SaveBug(Bug value) 
    { 
     // Bug save logic 
    } 

    public void SaveIncident(Incident value) 
    { 
     // Incident save logic 
    } 
} 

改進的設計只爲迎合需要轉移需要更改Persister.Save(IEntry)。我只是想演示讓代碼更脆弱的第一步。在現實和生產代碼中,您希望擁有BugPersister和IncidentPersister類,以符合Single Responsibility principle

希望這個更以代碼爲中心的例子是一個幫助。