2014-01-31 8 views
1

파일 레이아웃을 설명하는 템플릿을 기반으로 구분 된 또는 고정 폭 파일을 가져올 파일 가져 오기 코드를 작성 중입니다.인터페이스 내에 인터페이스 구현

public interface IFileTemplate 
{ 
    string Name { get; set; } 
    bool IgnoreEmptyLines { get; set; } 
} 

DelimitedFileTemplate 클래스와 FixedWidthFileTemplate 클래스에 의해 사용됩니다

나는 인터페이스 IFileTemplate를 만들었습니다.

public interface IFileTemplateColumn 
{ 
    int ID { get; set; } 
    string Name { get; set; } 
    bool Ignore { get; set; } 
} 

이 인터페이스는 다음 DelimitedTemplateColumn 클래스에 의해 사용되며 FixedWidthTemplateColumn 클래스 :

는 또한 템플릿을 구성하는 각 열을 지정하는 인터페이스를 가지고있다.

List<IFileTemplateColumn> Fields { get; set; } 

내 문제는 내가의 목록을 구현하기 위해 왔어요 때이다 : 모두 DelimitedFileTemplate 및 FixedWidthFileTemplate 클래스로

내가 목록 IFileTemplate 컬럼의 일원했습니다 열 목록을해야합니다 예를 들어 DelimitedFileTemplate 및 FixedWidthFileTemplate 클래스 :

public class FixedWidthFileTemplate : IFileTemplate 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public List<FixedWidthFileTemplateColumn> Fields { get; set; } 
} 

나는 시도하고 List<DelimitedFileTemplateColumn> 또는 List<FixedWidthFileTemplateColumn>List<IFileTemplateColumn>을 구현하는 경우 컴파일러는 그렇지 않은 것을 불평 일치하는 List<IFileTemplateColumn>.

이 내용을 이해할 수 있지만 ITemplateInterface에 열 목록을 포함시키지 않는 것이 좋습니다. 내가 생각할 수있는 유일한 방법은 Delimited 및 FixedWidth 클래스에 List<IFileTemplateColumn>을 사용하고 getter 속성을 구분 된 또는 고정 폭 열 목록으로 캐스팅하도록하는 것입니다. 그러나 약간의 코드 냄새가 나는 것 같습니다. 누구든지이 일을 위해 더 좋은 방법을 제안 할 수 있습니까?

interface IFileTemplate<T> where T : IFileTemplateColumn 
{ 
    List<T> Fields { get; set; } 
} 

DelimitedFileTemplateIFileTemplate<DelimitedFileTemplateColumn> 등등 구현 :

+0

인터페이스를 구현 한 클래스에 코드를 추가하는 것이 좋습니다. 더 읽기 쉬울 것입니다. –

+0

@FaisalHafeez 좋은 제안입니다. 업데이트되었습니다. – GrandMasterFlush

+0

나는 물러서서 왜 인터페이스가 있는지 묻습니다. 각 인터페이스를 구현하지만 객체가 아닌 공통 기본 클래스가없는 세 가지 클래스가 있습니까? –

답변

1

이 디자인 문제에 냄새 나는 적합하지 솔루션은 제네릭입니다.

아마도 파일 템플리트 간의 모든 차이는 IFileTemplateColumn으로 만 정의 할 수 있으며 FileTemplateColumn 클래스 관계 당 FileTemplate 클래스가 하나만있는 FileTemplate<IFileTemplateColumn> instend로 작업을 단순화 할 수 있습니다.

공장 방법으로

업데이트 : IFileTemplate<IFileTemplateColumn> Create :이 방법의 소비자가 열 목록에 액세스 할 수 있어야하는 경우, 메소드 서명이 콘크리트 템플릿 열을 포함해야합니다.예를 들어 :

interface IFileTemplate { ... } 
interface IFileTemplate<T> : IFileTemplate where T : IFileTemplateColumn 
{ 
    List<IFileTemplateColumn> Columns { get; set; } 
} 
: 메소드의 소비자가 목록에 관심이 없을 경우

DelimitedFileTemplate Create 

또는

interface IFactory<T> where T : IFileTemplateColumn 
{ 
    IFileTemplate<T> Create(); 
} 

class DelimitedFactory : IFactory<DelimitedFileTemplateColumn> 
{ 
    IFileTemplate<DelimitedFileTemplateColumn> Create() 
    { 
     return new DelimitedFileTemplate(); 
    } 
} 

는, (많은 IEnumerable<T> : IEnumerable 같은) 더 일반적인 인터페이스를 소개합니다

그러면 IFileTemplate Create() 메서드는 열에 관계없이 구체적인 FileTemplate을 반환 할 수 있습니다.

이러한 종류의 제네릭 사용법을 사용해 보았지만 전파하는 경향이 있습니다 (이 예제에서는 열 계층 구조가 FileTemplate 계층 구조에서 복제되고 공장 계층 구조에서 복제 될 수 있음). 때로는 디자인의 결함이 드러납니다. IFileTemplate 계층을 하나의 기본 매개 변수화 된 FileTemplate 클래스로 현명하게자를 수 있었다면, 이것은 분명히 갈 길이었습니다. 이것은 내가 자주 사용하는 방식입니다. 가장 작은 부분을 정의하고, 계층 구조가 복제되는 경향이있는 경우 알고리즘의 일부분을 '최소 부품 클래스'로 옮길 수 있습니다.

+0

답변을 주셔서 감사합니다. MVVM을 사용하여이 솔루션을 구현할 때 두 번째 제안을 따르는 것이 더 쉬웠습니다.목록에 여러 유형의 템플리트가 포함될 경우 모든 템플리트 목록을 리턴하는 것이 관리하기가 너무 어려웠습니다. – GrandMasterFlush

+1

@ GrandMasterFlush 당신이 혼자 힘으로 다룰 수있어서 다행입니다. 나는 마침내 이것에 되돌아 갈 약간의 시간을 가졌습니다. 업데이트를 보았을 때, 비슷한 문제가있었습니다. – lisp

+0

업데이트 해 주셔서 감사합니다. 몇 가지 더 살펴 보겠습니다. 건배. – GrandMasterFlush