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

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

我有一个相当通用的接口,搜索“某些东西”并返回Result。接口可以由几个类来实现,每个类都返回它们自己的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; 
    } 
} 

DiskResult包含的结果是特定于DiskRespository额外信息。如果我创建了另一个实现IRepository的类,那么该特定实现可能有自己的一组元数据,这些元数据对于该类是唯一的。

最后,我想我的搜索控制器看起来像这样:

我可以很容易地展示在我ResultData财产,但有一个很好的模式,以显示元每个课程从Result派生?我可以有一大堆if语句来检查这个类是否属于某种类型,但是感觉有点笨拙。有没有更好的方法去做我想要达到的目标?

回答

0

你可以做IRepository一个通用的接口,如:

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

您可以在结果类virtual方法,这将显示结果。你的孩子班可以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(); 
    } 

} 

希望这有助于你。

+1

这违反了SRP。演示文稿应该与域分开。 – Eranga 2012-02-27 04:04:07

1

其中一条注释正确地指出,将虚拟Display()添加到Result类违反了单责任原则。完全正确。

这里是你的问题的困难:因为你想要做这样的事情:

private IRepository[] _repositories; 

...有没有办法避免这样做在运行时类型检查。编译器不知道将返回从结果派生的子类。所有它知道你的Repository返回一个Result派生对象。

在另一方面,如果你使用泛型:

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实现其经过的元数据和正确的结构它。