2012-02-27 2 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 속성을 표시 할 수 있지만,에 대한 메타 데이터를 표시 할 수있는 좋은 패턴이있다 :

결국

, I는 다음과 같이 내 검색 컨트롤러를하고 싶습니다 각 클래스는 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

의견 중 하나는 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 %에 충분합니다. 예를 들어 DiskResultDescription 속성에 폴더 등을 포함 할 수 있습니다. 메타 데이터는 툴팁 또는 상세보기로 표시 될 수 있습니다.

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

을 그리고 메타 데이터와 제대로 구조를 통해가는 DiskResultHtmlRenderer 구현이 : 그 부족의 경우

나는 너무 렌더링 인터페이스를 만들 것입니다.

관련 문제