Шаблон проектирования для группировки полей и структурирования данных в плоский файл

1

Я использую библиотеку FileHelpers С# для чтения файла в массив настраиваемых объектов, которые будут обработаны. Например, определение частичного файла:

[FixedLengthRecord]
public class Row
{
    [FieldFixedLength(9)]
    [FieldTrim(TrimMode.Right)]
    public string Ssn;

    [FieldFixedLength(15)]
    [FieldTrim(TrimMode.Right)]
    public string LastName;

    ...
}

Я стараюсь придерживаться принципов ООП при этом, и я заметил, что некоторые поля имеют естественную группировку (например, SSN и ClientID, EmployerID и EmployerName и т.д.), Поэтому я попытался разбить их на отдельные классы (например, Client и Employer). Но это кажется проблематичным, потому что некоторые из полей должны быть разделены между объектами (например, ClientID должен знать соответствующий EmployerID).

Чтобы еще больше усложнить ситуацию, я хотел бы добавить поля с атрибутом [FieldNotInFile] к определениям классов, потому что во время обработки мое приложение будет запрашивать записи базы данных, соответствующие определенному полю строки, и заполнять соответствующую строку [FieldNotInFile] ( например, получить имя клиента FName из базы данных на основе SSN поскольку оно не находится в файле).

Как бы вы это структурировали? Я вроде как хочу сохранить всю строку файла как один класс, но она приближается к 75 полям, что кажется смешным. Мысли?

Теги:
class
oop
design-patterns
filehelpers

3 ответа

1
Лучший ответ

Класс FileHelpers - это просто способ определения спецификации плоского файла с использованием синтаксиса С#.

Таким образом, классы FileHelpers являются необычным типом класса С#, и вы не должны пытаться использовать принятые принципы ООП. (Существует много способов, по которым класс FileHelpers нарушает принципы ООП, наиболее очевидно, что он требует использования открытых полей вместо свойств). FileHelpers не должны иметь свойств или методов, кроме тех, которые используются библиотекой FileHelpers.

Представьте, что класс FileHelpers является "спецификацией" вашего формата CSV. Это должна быть его единственная роль. Затем, если вам нужны записи в более "нормальном" объекте, тогда сопоставьте результаты с чем-то лучшим:

FileHelperEngine engine = new FileHelperEngine<FileHelpersOrder>(); 
var records = engine.ReadFile("FileIn.txt");

var niceOrders = records.Select(
    x => new NiceOrder() 
       { Number = x.Number,  
         Customer = x.Customer 
         // etc.
       });

Если FileHelpersOrder является вашей спецификацией CSV, а класс NiceOrder будет подходящим классом ООП со свойствами, методами и т.д. По мере необходимости.

  • 0
    Итак, вы говорите, что создадите другой класс, который почти идентичен определению строки файла, и поместите все методы туда? Это имеет смысл, просто кажется немного излишним.
  • 0
    Именно так. Это кажется немного избыточным, но спецификация файла CSV не всегда отображается точно на соответствующий объект, поэтому должно быть разделение.
1

В использовании файловых помощников я считаю класс FileHelper представлять запись в файле. Атрибут, который вы помещаете в начало класса (FixedLengthRecord или DelimitedRecord), напоминает вам об этом - это запись файла, а не модель фактического объекта.

Это означает, что если вам нужен объект, который моделирует сущность, вам нужно будет сделать много копий из класса FileHelper в ваш класс сущностей.

У меня много классов FileHelper с примерно 75 полями - каждый из этих классов представляет собой спецификацию файла, которая часто бывает большой. Но они по-прежнему очень удобны в обслуживании - просто откройте спецификацию и файл кода рядом и опустите список полей, чтобы найти какие-либо изменения, которые вам нужно внести.

Однако я разделил классы для заголовков, трейлеров и разных типов строк. Затем я бы использовал механизм MultiRecord, чтобы решить, какой класс использовать.

1

Я не уверен в определенном шаблоне, но я не буду включать дополнительные поля в класс, предназначенные для десериализации/анализа вашего плоского файла. Вы можете добавить поле базы данных в унаследованный класс.

  • 0
    Наследование не похоже на правильное решение, потому что это не отношения "есть".
  • 0
    Я бы все равно оставил поля, связанные с файлом, в своем собственном классе. Таким образом, это очевидные отношения 1 к 1. Вы создаете класс со всеми полями, которые заполняются из нескольких классов источников данных, используя фабричный шаблон.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню