2009-01-19 3 views
1

C# (.NET 3.5)의 특정 데이터 구조를 가장 잘 설명하는 방법을 결정할 때 몇 가지 문제가 있습니다.상위 클래스 멤버에 액세스 할 수 있도록 C#에서 클래스 heirachy를 구조화하는 가장 좋은 방법은 무엇입니까?

명령 줄 프로그램의 입력을위한 텍스트 파일을 만드는 클래스 라이브러리를 만들어야합니다. 수십 개의 파일 형식이 있지만 대부분 머리글, 바닥 글 및 기타 몇 가지 속성이 있습니다.

그래서 파일은 다음과 같습니다

timestamp filename company 

....lots of attributes that make up the file body.... 

footerdetail1 footerdetail2 footerdetail3 

지금 파일 형식이 수십에서 정말 단지 세 고유의 머리글/바닥 글 콤보가 있습니다.

class BaseFileType { 

public List<HeaderItems>; 
public List<BodyItems>; 
public List<FooterItems>; 
FileType filetype; 
String filename; 

public BaseFileType1 (FileType filetype,String filename) { 

    this.filetype = filetype; 
    this.filename = filename; 


    // add stuff to the header list 
    // add stuff to the footer list 


} 

    // some methods to find items in the header/ footer lists 

} 

class ActualFile1 : BaseFileType { 

    ActualFile() { 


    //add stuff to the bodyitems list 
    } 


    //some other generic methods 


} 
는 것은이

, 내가 생성자를 상속 할 :

그래서 나는 headerItems 및 footeritems의 대부분을 포함하는 부모 클래스를 확인한 다음 파생 클래스의 실제 파일 형식을 구현하려면 파생 클래스의 기본 클래스에서,하지만 내가 이것을 읽은 것에서 할 수 없습니다. 가장 좋은 전략은 무엇입니까?

내 작업에 대해 갈이, 심지어 가장 좋은 방법입니다 (부모 매개 변수) 기본 :

ActualFile() : 내가 그렇게처럼 내 파생 클래스의 생성자에서 기본 생성자를 호출 할 수 보았다

? 결국이 모든 파일 정보에 대한 최상의 데이터 구조를 찾고 있으므로이 클래스를 만들 때 자신을 반복 할 필요가 없습니다.

사람들에게 어떤 다른 대안이 효과가 있을까요? 하나의 FileFactory가 필요한 구조를 포함하는 클래스를 생성합니까?

답변

0

이것은 템플릿 방법으로 해결 될 수있는 것처럼 보입니다.(마지막 장소는 각각의 고유 파일 형식

public class LetsSayCSVGenerator : UniqueHeaderFooterCombination1 
{ 
    protected override void AddBody() 
    { 
    Console.WriteLine("csv body items"); 
    } 
} 
위한

abstract public class UniqueHeaderFooterCombination1 : DocumentGenerator 
{ 
    protected override void AddHeader() 
    { 
    Console.WriteLine("unique combination1 header"); 
    } 
    protected override void AddFooter() 
    { 
    Console.WriteLine("unique combination1 footer"); 
    } 
} 

같이 마지막 구체적인 클래스 패턴 : 3 고유 한 조합마다

public abstract class DocumentGenerator 
{ 
    abstract protected void AddHeader(); 
    abstract protected void AddBody(); 
    abstract protected void AddFooter(); 

    // Template Method http://en.wikipedia.org/wiki/Template_method_pattern 
    public FileInfo Generate(string sFileName) 
    { 
    FileInfo f = null; 
    //create file 

    // either pass in the file to the below methods or use member vars + an additional write step 
    AddHeader(); 
    AddBody(); 
    AddFooter(); 

    // write out everything to the file 
    return f; 
    } 
} 

다음에, 중간 레벨의 클래스를 사용하는

FileType에 적합한 유형의 Generator를 반환하기 위해 Factory와 연결하면 작업이 완료됩니다.

abstract class DocumentGeneratorFactory 
{ 
    public static DocumentGenerator GetGenerator(FileType eFileType) 
    { 
    switch (eFileType) 
    { 
     // a hash of FileType => Generator 
     default: 
     return new LetsSayCSVGenerator(); 
    } 

    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
    DocumentGenerator d = DocumentGeneratorFactory.GetGenerator(FileType.CSV); 
    FileInfo f = d.Generate("ItsAlive.CSV"); 
    } 
} 
0

여러분이 말했듯이 생성자는 상속되지 않습니다.

생성하는 동안 값을 알아야하는 경우 파생 클래스가 생성자에서 세부 정보를 제공하도록하는 것이 이상적인 경우입니다. 당신이, 추상적 인 속성을 고려하지 않는 경우 파생 클래스가 제공해야합니다 :

// base-class 
public abstract FileType FileType {get;} 

// derived-class 
public override FileType FileType { 
    get {return FileType.Excel;} // or whatever 
} 

주 당신이 그것을 문서화하지 않는 매우 명확하게 (그리고 의미를 이해) 가상 메소드를 호출하지 않아야합니다 (예를 위와 같이) 파생 된 유형의 생성자가 아직 실행되지 않았으므로 - 그러나 그 이후에는 괜찮습니다.

file-name은 실제로 하위 유형에 종속되지 않으므로 나는 ctor 매개 변수로 남겨 둡니다.

0

머리글 & 바닥 글을 읽는 기본 클래스를 만들 수 있으며 중간에있는 특성에 액세스 할 수 있습니다. 그런 다음 수십 개의 특정 속성 독자가 구현할 인터페이스를 정의하십시오. 인터페이스는 "기본 클래스"를 받아 들일 필요가있을 수 있으며 각 구현은 중간에있는 물건을 읽는 방법을 정의합니다.

실제로는 공통 부분을 읽고 일반적인 방법으로 속성에 액세스 할 수 있습니다. 이 부분은 느슨하게 결합되므로 변경 사항이 덜 제한적입니다.

관련 문제