2011-05-16 39 views
1

請考慮以下接口:如何用接口ID之類的東西替換枚舉?

interface IFile 
{ 
    // Members 
}; 

interface IAudioFile : IFile 
{ 
    // Members 
}; 

interface IVideoFile : IFile 
{ 
    // Members 
}; 

enum ContentType 
{ 
    Audio, 
    Video 
}; 

interface IProvider 
{ 
    HashSet<ContentType> GetSupportedTypes(); 
    IList<IFile> GetFiles(ContentType contentType); 
}; 

我認爲的ContentType枚舉是多餘的。 有什麼辦法可以使用接口標識符而不是枚舉類型?

對界面設計的任何評論都非常感謝。

+2

是什麼讓你認爲你的枚舉是多餘的? – 2011-05-16 10:50:10

+0

@Abdul,只是因爲接口類型映射到枚舉值: IAudioFile => ContentType.Audio; IVideoFile => ContentType.Video – 2011-05-16 11:00:03

回答

3

這真的取決於你想完成什麼,但我一個選項,你可能想看看在使用泛型,使IProvider是如此

interface IProvider 
{ 
    IList<IFile> GetFiles<T>() where T: IFile; 
} 

可以像這樣

實施
public void ProviderConcrete() 
{ 
    public IList<IFile> GetFiles<T>() 
    { 
     if(typeof(t) == typeof(IAudioFile)) 
      .... get Audio files 

    } 
} 

,並呼籲像這樣

public void Caller() 
{ 
    var files = GetFiles<IAudioFile>(); 
} 
+0

好的,很好!但是如何獲取有關支持的文件類型的信息(請參閱GetSupportedTypes)? – 2011-05-16 11:02:21

+0

嗯,在什麼情況下你需要調用GetSupportedTypes? – 2011-05-16 12:23:41

+0

客戶端應該有可能獲得一組受支持的類型,然後逐個獲取僅受支持的類型。 – 2011-05-16 12:34:41

0

通常情況下,最好是喜歡寫東西這樣的:

void method(IFile file) { 
    file.DoYourThing(); 
} 

void method(ContentType id) { 
    switch (id) { 
    case ContentType.Audio: 
     file.DoThis(); 
     break; 

    case ContentType.Video: 
     file.DoThat(); 
     break; 
    } 
} 

這是因爲開關通常成爲維護的噩夢隨着時間的推移,它的容易出錯了。

我的建議是,當您需要switchesif-else鏈時,您應該考慮將方法插入到已存在的類層次結構中或創建一個新的類。您應該努力編寫看起來像您在第一個代碼片段中看到的代碼。

像往常一樣,這是通用的,所以它可能不適用於您的特定問題。

0

我認爲這裏的意思是返回的列表包含「基礎」對象。

如果你不喜歡,你可以創建一些重載像

IList<IAudioFile> GetAudioFiles(); 
IList<IVideoFile> GetVideoFiles(); 
+0

對不起,但我沒有提到過,文件的類層次結構可能會稍後增長。所以,我需要更靈活的機制。 – 2011-05-16 11:05:54