2012-02-27 7 views
4
class Result 
{ 
    public string Data { get; set; } 
} 

interface IRepository 
{ 
    Result[] Search(string data); 
} 

派生型を返す私は「何か」を検索し、Resultを返し、かなり一般的なインタフェースを持っています。 IRepositoryインターフェイスはいくつかのクラスで実装でき、それぞれ独自の独自のメタデータで独自のResultを返します。例えば、私は、ディスク上のデータを検索DiskRepositoryを持つことができます。インタフェースは

class DiskResult : Result 
{ 
    public int FileSize { get; set; } 
    public DateTime LastModifiedDate { get; set; } 
} 

class DiskRepository : IRepository 
{ 
    public Result[] Search(string data) 
    { 
     // ... 
     DiskResult[] results = GetDataFromSomewhere(); 
     return results; 
    } 
} 

DiskResultDiskRespositoryに固有の結果についての追加情報が含まれています。 IRepositoryを実装する別のクラスを作成した場合、その特定の実装には、そのクラスに固有の独自のメタデータセットがある可能性があります。最後に

、私は私の検索コントローラは、次のようになりたいのですが:

私は簡単に私のResultクラスにDataプロパティを表示することができますが、メタデータを表示するための良好なパターンがありますResultから派生する各クラス? ifの文を使って、クラスが型かどうかを調べることができますが、それはちょっと鈍い感じです。私が達成しようとしていることをするためのより良い方法はありますか?あなたは結果を表示する結果クラスのvirtualメソッドを持つことができ

interface IRepository<T> 
{ 
    T[] Search(string data); 
} 

答えて

0

あなたがIRepository汎用インタフェースのように作ることができます。あなたの子供のクラスはoverrideとすることができ、独自の実装を与えることができます。これを行うとDisplayメソッドを呼び出すと、Resultオブジェクトはそれぞれのメソッドを呼び出して表示を行います。

この

class Result 
{ 
    public virtual void Display() 
    { 
      //Your Code 

    } 
    //Your Code 
} 

class DiskResult : Result 
{ 
    public override void Display() 
    { 
      //Your Code 
    } 
    //Your Code 
} 

ような何かあなたのDisplay方法

public void Display(string data) 
{ 
    Result[] results = _repositories.Search(data); 

    // Display results 
    foreach(var result in results) 
    { 
     result.Display(); 
    } 

} 

が、これはあなたのお役に立てば幸いです。

0

+1

これはSRPに違反します。プレゼンテーションはドメインから分離する必要があります。 – Eranga

1

コメントの1つは、Resultクラスに仮想Display()を追加することがSingle Responsibility Principleの違反であることを正しく指摘しています。完全に真実。ここで

は、あなたの質問でこするです:あなたはこのようなことをやりたいので:

private IRepository[] _repositories; 

...実行時に型チェックを行うことを避けるための方法はありません。コンパイラは、サブクラス型の結果から導出される結果が何であるか分かりません。あなたのリポジトリが結果派生オブジェクトを返すことはすべて知っています。一方

、あなたがジェネリック医薬品を使用する場合:

interface IRepository<T> where T : Result 
{ 
    T[] Search(string data); 
} 

を...あなたは、コンパイル時に、あなたは、このように型チェックの必要性をなくす、扱っている結果のどのようなサブクラスのタイプを知っているだろう、そして最初のアプローチから続く "if"ステートメントの長い文字列です。

あなたがジェネリックを使用してに固執することができるなら、あなたはこのようなものを行うことができます:だから

interface IResultDisplayService<T> where T : Result 
{ 
    void Display(T result); 
} 

、私は私の質問があると仮定します。それは、これらのリポジトリの配列を格納することが不可欠ですか?どのような現実世界の使用シナリオがありますか?

1

私はそのためのリポジトリのインターフェースを使用しますが、新しいものを作成しないでしょう。

public interface ISearchProvider 
{ 
    IEnumerable<SearchResultItem> Search(string keyword); 
} 

public interface ISearchResultItem 
{ 
    string Title {get; } 
    string Description {get; } 
    NameValueCollection Metadata {get; } 
} 

タイトルと説明は、検索例の90%のための十分なはずです。たとえば、DiskResultには、Descriptionプロパティにフォルダなどが含まれている可能性があります。メタデータは、ツールヒントまたは詳細ビューで表示できます。

それが十分ではない場合、私はあまりにもレンダリングインターフェイスを作成します。

public interface ISearchResultRenderer 
{ 
    bool IsValidFor(Type type); 
    void Render(Stream stream); 
} 

とメタデータと構造きちんとそれを通過DiskResultHtmlRenderer実装を持っています。

関連する問題