Как сохранить мои функции (объекты/методы) "скудные и средние",

во всех (Agile) статьях, которые я читал об этом: сохраняйте свой код и функции небольшими и легко проверяемыми.

Как мне это сделать с классом "контроллер" или "координатор"?

В моей ситуации мне нужно импортировать данные. В конце концов, у меня есть один объект, который координирует это, и мне было интересно, есть ли способ сохранить координатор lean (er) и mean (er).

Мой координатор теперь выполняет следующий (псевдокод)

//Write to the log that the import has started
Log.StartImport()
//Get the data in Excel sheet format
result = new Downloader().GetExcelFile()
//Log this step
Log.LogStep(result )
//convert the data to intern objects
result = new Converter().Convertdata(result);
//Log this step
Log.LogStep(result )
//write the data
result = Repository.SaveData(result);
//Log this step
Log.LogStep(result )

Имхо, это один из тех, кто знает все классы или, по крайней мере, одно из них "не тощий и скупой"? Или я беру эту скудную и среднюю вещь далеко, и невозможно ли запрограммировать импорт без какого-либо "живого" импортера/координатора?

Мишель

ИЗМЕНИТЬ это на самом деле вопрос два-в-одном: один из них, как проверить его, во-вторых, если это нормально, чтобы иметь координатор "знать все/клеить все вместе"

Ответ 1

Я уверен, что многие люди не согласятся, но я думаю, что ваш метод в целом достаточно скуден. Важнейший бит, который вы здесь не видите, - это инъекция зависимостей (также называемая инверсией управления) - поэтому вместо новичка Downloader, Converter и т.д. Внутри вашего метода вы должны определить интерфейсы для этих классов и "вставить" их в конструктор вашего класс:

private Downloader downloader;
private Converter converter;

public MyClass(Downloader downloader, Converter converter)
{
  this.downloader = downloader;
  this.converter = converter;
  //same with repository, it can't be a static class anymore
}

то вы просто используете эти экземпляры в своем методе:

//Write to the log that the import has started
Log.StartImport()
//Get the data in Excel sheet format
result = downloader.GetExcelFile()
//Log this step
Log.LogStep(result )
//convert the data to intern objects
result = converter.Convertdata(result);
//Log this step
Log.LogStep(result )
//write the data
result = repository.SaveData(result);
//Log this step
Log.LogStep(result )

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

Примеры использования RhinoMocks приведены в их документации: http://ayende.com/wiki/Rhino+Mocks+Documentation.ashx

Не стесняйтесь задавать другой вопрос, если вы застряли:)

Ответ 2

У меня была аналогичная проблема, и я решил, что это действительно нужно посмотреть на SRP (Single Responsibility Principal).

ExcelFileReader, который может читать файл excel и возвращать набор List (lines)

Parser Задача заключается в анализе строк, возвращаемых из ExcelFileReader с помощью разделителя

Импортер, который обрабатывает импорт DataSet, возвращаемого из FileParser, в правильные таблицы.

Это сохраняет его в проверяемой форме, поскольку ExcelFileReader не зависит от Parser или Importer. Это касается и Parser, а также его проверки, просто передав ему TextReader.

Помогает ли это?

Ответ 3

Очень часто существует класс, который делает то, что я считаю, шаблон посредника.

Один из способов, который я нашел для борьбы с классами, которые должны иметь коллаборационисты (к чему вы сейчас работаете), состоит в том, чтобы выполнить Mock Unit Testing.

Вы по существу сворачиваете своих коллаборационистов и устанавливаете ожидания для тех, кто сотрудничает.

К сожалению, вы используете С#, и я не знаю каких-либо Mock-библиотек для С#. Однако я уверен, что Google может помочь вам найти макетную библиотеку.

Вместо макетной библиотеки вы можете просто реализовать или расширить классы соавторов и переопределить и реализовать методы, которые вы ожидаете вызвать, с помощью методов, которые производят ожидаемый результат.

Как было отмечено Майклом, это намного проще, если у вас есть приложения для встраивания в зависимости от ваших сотрудников.

Ответ 4

Ваши комментарии и регистратор (singleton?) слишком шумные:

Log.StartImport();
result = new Downloader().GetExcelFile()
Log.Step(result);
result = new Converter().Convertdata(result);
Log.Step(result);
result = Repository.SaveData(result);
Log.Step(result);

И поскольку у вас есть три шага, которые должны произойти вместе, оберните их в Converter. Используя DI, войдите в Converter a Downloader и a Repository. Теперь вы получаете:

Log.StartConvert();
convert.ExcelToRepository(); //passed in with DI

Обратите внимание, что все результаты шага журнала выполняются в соответствующих действиях.