Итак, как я понимаю, шаблон контекста является анти-шаблоном. Однако я столкнулся с проблемой, которую мне нужно решить, что, вероятно, оправдывает ее использование.Является ли это допустимым аргументом для шаблона Context?
У меня есть набор классов, которые реализуются с IParser
. Интерфейс IParser
требует, чтобы разработчики могли реализовать CanRead(Stream)
- где разработчик возвращает, выводит ли он поток в соответствующем формате для чтения. Так, например, CsvParser
будет читать поток и проверять, удовлетворяет ли оно регулярному выражению ([\w]*),
.
Далее они должны реализовать Parse(Stream)
, в котором разработчики возьмут Stream и проанализируют его по-своему, пока они возвращают перечислимые POCO из их проанализированных данных.
Теперь, пожалуйста, это руб. Существует несколько парсеров, таких как XmlParser
, CsvParser
и т. Д. Каждый Parser знает, как разбирать собственный формат, но данные поступают от сторонних пользователей. Мы не можем гарантировать, что макет их данных соответствует тому, что ожидает каждый из парсеров. То есть, хотя они могут очень хорошо находиться в действительных Xml или Csv, у них могут не быть одинаковые имена полей для сопоставления данных (один источник может иметь <DateTime>...</DateTime>
, другой может иметь <Time>...</Time>
) и т. Д.
Я не хочу обязательно приходится писать парсеры для каждого клиента, у которого могут быть небольшие вариации. Чтобы устранить эту проблему, я предлагаю, чтобы у меня был класс, который будет служить «картой». Это будет иметь свойства, которые будут называться ожидаемым именем поля и иметь значение реального имени/местоположения поля (в терминах файлов Csv это будет столбец). Это будет передано в метод Parse(Stream)
.
Однако, как я понимаю, это контекстный шаблон. Не говоря уже о том, что он несет дополнительную ответственность за класс парсера, поскольку он не только должен читать файл, но также должен отображать входные данные на выходе. Это также довольно уродливый способ приблизиться к вещам с точки зрения теста. Есть ли лучший способ приблизиться к этому?
EDIT: В истинном тест управляемой моды развития, я придумал решение, которое выглядит следующим образом:
IParser
«s метод синтаксического анализа теперьParse(Stream stream, string dateReference, string valueReference, string idReference)
.- Создайте новый интерфейс под названием
IFieldLocator<T>
со способомGetField(String fieldReference, T input)
.
Теперь для реализации:
CsvFile
является значение объекта, который принимает строку Csv в это конструктор и позволяет получить к нему доступ черезGetField(int lineNumber, int columnNumber)
.CsvFieldLocator
инвентарьIFieldLocator<CsvFile>
и это методGetField(string fieldReference, CsvFile input)
- это обертывание для доступа кCsvFile.GetField(int lineNumber, int columnNumber)
. Строка вfieldReference
является ссылкой на столбцы/строки в excel.CsvParser
занимаетIFieldLocator<CsvFile>
в своем конструкторе.
Вот как я решил эту проблему. Тем не менее, меня все еще интересует ваше мнение.