Программа анализирует лог-файлы - каждый лог-файл может иметь разный формат полей (фиксированная ширина, разделители-запятые и т. д.). Кроме того, каждый файл журнала состоит из нескольких разных типов журналов - каждый вид имеет различное определение поля). Например, файл журнала CSV может выглядеть так:
Файл журнала А
logType1, 10/1/2012, 12, abc logType2, a, b, c, d, 11/1/2012 logType1, 10/2/2012, 21, def logType2, e, f, c, d, 12/1/2012 logType3, 3.23, ....
Ниже приведен код. Сколько твердых принципов было нарушено в следующем коде? Один парень сказал, что список определения макета не следует смешивать с журналом синтаксического анализа. Так это как минимум нарушает SRP (или больше)? Каков наилучший способ рефакторинга структуры?
// Field
public interface IField { .... }
public class Field : IField { ... common field methods, etc.... }
public class FixedWidthField : Field { }
public class CommaDelimField : Field { ... }
// Log type
public interface ILogType<out T> where T : IField { ... IEnumerable<T> Fields { get; } }
public class LogType<T> : ILogType<T> where T : IField
{ ....
public LogType(..., List<T> fields) { ... Fields = fields; }
}
// File
public inteface ILogFile<out T> where T: IField { ... IEnumerable<ILogType<T>> LogTypeList { get; set; } }
public abstract class LogFile<T> : ILogFile<T> where T: IField
{ ....
public IEnumerable<ILogType<T>> LogTypeList { get; set; }
public virtual string Row { get { ... } set { ...} }
public string GetParsedFieldString() { ... }
}
public class CommaDelimLog : LogFile<CommaDelimField>
{
public override string Row { get { ... } set { ...code to parse the line...} }
public override string GetParsedFieldString() { ... }
}
// The following initilize code store all the layout information
public static List<ILogFile<IField>> LogFileList = new List<ILogFile<IField>>
{
new CommaDelimLog("logFileA", ...., new List<ILogType<CommaDelimField>> {
new LogType<CommaDelimField>("logType1", ... new List<CommaDelimField>{ .... }
new LogType<CommaDelimField>("logType2", ... new List<CommaDelimField>{ .... }
....
}),
new CommaDelimLog("logFileB", .... a long long list
Основная программа получает элемент из LogFileList в соответствии с шаблоном имени файла, читает файлы журнала построчно и присваивает свойство Row
, а затем получает проанализированную строку.