2011-03-01 151 views
0

我有一个关于继承问题,所以我将描述如下情况:继承和多重构造

我读包含日志的文本文件。 (每行一个日志) 每个日志线将具有以下格式: “日期类型描述”

然而,根据日志的“类型”,我将不得不解析“说明”不同,拉出不同的领域。

下面是一些例子:

5/1/2011 Information Field1, Field2, Field3 
5/2/2011 Error  Field1 

- 所以,我试图做的是这样的:
- 获得一个线路输出日志
的-Parse根据图案为“日期类型说明”
-Look在‘类型’字段,并创建新的对象/解析需要说明

public class Log 
{ 
    public DateTime Date; 
    public String Type; 
    public String Description; 

    public Log(String line) 
    { 
     this.Date = GetDate(); 
     this.Type = GetType(); 
     this.Description = GetDescription(); 
    } 
} 

public class InformationLog : Log 
{ 
    public String Field1; 
    public String Field2; 
    public String Field3; 

    public InformationLog(Log log) 
    { 
     this.Field1 = GetField1(log.Description); 
     this.Field1 = GetField2(log.Description); 
     this.Field1 = GetField3(log.Description); 
    } 
} 

public class Client 
{ 
    public void Main() 
    { 
     String line = ReadFileAndGetLine(); // Get a line from the file 
     Log log = new Log(line); 
     if(log.Type == "Information") 
      log = new InformationLog(log); // Is this right? 
    } 
} 

这是我想要的方式,但似乎这不是一个好习惯。 “log”变量将自身用作其自己的构造函数的参数。

我的问题是: 有没有这样做的标准方式?或者,这个实施有什么问题吗?

-
编辑:
另外,我应该提到:我的理由是,我会分析行一次走出日期和类型,然后再分析它,以获得更精细的细节。
我决定使用继承,所以我不必解析出Date和Type字段两次。

+1

为什么不只是使用'Log'来做条件分析呢? – 2011-03-01 14:22:02

+0

@Mr。失望:每种类型的日志都有不同的参数,所以我不想把“Field1,Field2,Field3等”如果它们不是必需的,则记录在“日志”中。 – Eric 2011-03-01 14:24:41

+1

赞赏,但如果它们总是包含'Type'和'Description',那么这仍然可以发生在基类中。 – 2011-03-01 14:27:33

回答

2

按我的意见,为什么不只是做一些有点像这样:

public enum LogEntryType 
    { 
     Error = -1, 
     Information = 0, 
    } 

    public class LogEntry 
    { 
     public string Raw; 
     public DateTime Date; 
     public LogEntryType Type; 
     public string Description; 

     public LogEntry(String line) 
     { 
      Raw = line; 
      Date = ParseDate(); 
      Type = ParseType(); 
      Description = ParseDescription(); 
     } 

     public string ParseDescription() 
     { 
      var result = string.Empty; 
      switch(Type) 
      { 
       case LogEntryType.Error: 
        //parse here 
        break; 
       case LogEntryType.Information: 
        //parse here 
        break; 
      } 
      return result; 
     } 
    } 

我注意你在派生类中有字段,但是可以在这里解释描述;不过,我可以看到为什么人们可能想要将它转移到实际上知道的地方如何解析描述,在这种情况下,您可以使用在另一个答案中建议的工厂模式,或者实现“属性包”类型场景 - 但我认为,这些日子里,强烈的打字习惯会逐渐消失。

另一个建议虽然与初次尝试非常相似,但倾向于封装类型的管理,而不是让分离的类处理这些东西 - 一种模式(表面上),如Exception,其中有一个根条目,内部条目:

public enum LogEntryType 
    { 
     Error = -1, 
     Information = 0, 
    } 

    public class LogEntry 
    { 
     public string Raw; 
     public DateTime Date; 
     public LogEntryType Type; 
     public string Description; 

     public InnerLogEntry InnerEntry; 

     public LogEntry(String line) 
     { 
      Raw = line; 
      Date = ParseDate(); 
      Type = ParseType(); 
      //parse the 'raw' description... 
      Description = ParseDescription(); 
      //determine the inner entry type... 
      switch (Type) 
      { 
       case LogEntryType.Error: 
        InnerEntry = new ErrorLogEntry(this); 
        break; 
       case LogEntryType.Information: 
        InnerEntry = new InformationLogEntry(this); 
        break; 
      }     
     } 
    } 

    public abstract class InnerLogEntry 
    { 
     protected LogEntry Parent; 

     public InnerLogEntry(LogEntry logEntry) 
     { 
      Parent = logEntry; 
     } 
    } 

    public class InformationLogEntry : InnerLogEntry 
    { 
     public InformationLogEntry(LogEntry logEntry) 
      : base(logEntry) 
     { 
      //parse custom data 
     } 
    } 

    public class ErrorLogEntry : InnerLogEntry 
    { 
     public ErrorLogEntry(LogEntry logEntry) 
      : base(logEntry) 
     { 
      //parse custom data 
     } 
    } 
+0

谢谢,但是,我看不出如何去存储“Field1,Field2等”。参数? - “说明”可能包含3个字符串,或者可能有DateTime和Double等。 – Eric 2011-03-01 14:28:55

+0

我喜欢你的第二次尝试。对我来说,其实看起来像一个抽象工厂。我认为这是我想要进入的更多方向,谢谢。 – Eric 2011-03-01 14:48:13

+0

没问题,我认为它比某些情况更适合 - 特别是如果它适合你的话。你也可以从'LogEntry'派生'InnerLogEntry',这样每个条目都可以有一组基本的数据和/或他们自己的孩子 - 这需要更多的调整,但这只是一个想法。 – 2011-03-01 14:52:36

4

尝试使用Factory pattern

static class LogFactory 
{ 
    public static Log Create(String line) 
    { 
     if(GetType(line) == "Information") 
      return CreateInformationLog(line); 
     return CreateLog(line); 
    } 

    private static Log CreateLog(String line) 
    { 
     return new Log(line); 
    } 

    private static Log CreateInformationLog(String line) 
    { 
     return new InformationLog(line); 
    } 
} 

,然后尝试用

String line = ReadFileAndGetLine(); // Get a line from the file 
    Log log = LogFactory.Create(line); 
+0

谢谢。有没有办法保留字段“日期”和“类型”而不必调用“GetType(line)”两次?看起来InformationLog(line)的构造函数将不得不再次调用GetType(line)。 – Eric 2011-03-01 14:34:54

+0

然后你可以扩展构造函数到'日志(字符串行,字符串类型)' – Stecya 2011-03-01 14:50:09