Полностью Арбитражный C # Вопрос - PullRequest
2 голосов
/ 22 апреля 2009

Допустим, у вас есть объект, который, например, мы будем называть ScoreHotChicksEngine. И скажем, что конструктор ScoreHotChicksEngine ожидает, что ему будет передан IDataReader, содержащий значения свойств, относящиеся, по-видимому, к оценке горячих цыпочек для одиноких вундеркиндов.

ScoreChicksEngine(IDataReader reader);

Хорошо, вот что я хотел бы собрать для ввода ...

Как разработчик, вы сочтете более полезным предположить, что читатель должен быть прочитан до его передачи в ScoreChicksEngine

IDataReader = command.ExecuteReader();
reader.Read();
ScoreChicksEngine SCE = new ScoreChicksEngine(reader);

или вы предполагаете, что сам механизм будет вызывать эту функцию и, возможно, иметь дело с пустыми значениями?

IDataReader  = command.ExecuteReader();
ScoreChicksEngine SCE = new ScoreChicksEngine(reader);
if (SCE.HasReaderData()) doSomething();

Ответы [ 8 ]

6 голосов
/ 22 апреля 2009

Разве вы не думаете о том, чтобы отделить сбор данных от алгоритма и использовать промежуточное решение (скажем, адаптер итератора)? Просто мои 0,02 доллара.

Смысл такой конструкции заключается в том, что алгоритм отвечает за вызовы для чтения данных по мере необходимости через адаптер. Адаптер скрывает коллекцию и любые ее конкретные аспекты, не относящиеся к решаемой проблеме.

3 голосов
/ 22 апреля 2009

Я бы выбрал первый метод. Второй метод нарушает принцип единой ответственности. Я бы также объявил входной параметр конструктора как IDataRecord, а не IDataReader. По сути, класс SCE создается на основе одной записи и не заботится о наборе записей.

1 голос
/ 22 апреля 2009

Это зависит от того, что ваш ScoreChicksEngine делает с читателем. Если читатель читает небольшой объем данных, лучше передать эти данные:

IDataReader = command.ExecuteReader();
ObservableCollection<HotChicks> Wowzer = reader.Read();
ScoreChicksEngine SCE = new ScoreChicksEngine(Wowzer);

Это также может быть коллекция с отложенной загрузкой, и вашему SCE будет все равно. В любом случае, я не думаю, что SCE должен вызывать что-либо для читателя, прежде чем он сможет получить доступ к результатам. Либо ваш IDataReader должен иметь внутреннюю логику для вызова функции чтения при первой попытке доступа к коллекции, либо должен вызывать ее в конструкторе. Что лучше, зависит от ваших обстоятельств. В любом случае, рекомендуем вам использовать ObservableCollection!

1 голос
/ 22 апреля 2009

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

  • Будет ли считываться текущая строка с использованием устройства чтения, или
  • Будет ли он перебирать все строки в считывателе и составлять список

Если первый случай, то я ожидал бы, что двигатель НЕ вызовет метод Read, если второй случай верен, я бы предположил, что двигатель находится на сиденье водителя и заботится о вызове Read. *

И это, вероятно, указывает на размышления о разъединении, как предлагалось ранее.

1 голос
/ 22 апреля 2009

Я бы использовал первый подход. Может быть, читатель вернет более одной записи, тогда вы могли бы сделать:

IDataReader = command.ExecuteReader();
while (reader.Read())
    list.Add(new ScoreChicksEngine(reader));

Фактически, в прошлом я создал класс-оболочку для считывателя данных (с такими методами, как GetInt32 (name), GetString ("name") и т. Д.

Таким образом, ScoreChicksEngine не имеет доступа к методам читателя, а только к методам класса-оболочки.

Приведенный выше пример будет выглядеть примерно так:

IDataReader = command.ExecuteReader();
while (reader.Read())
    list.Add(new ScoreChicksEngine(new MyDataReaderWrapper(reader)));
1 голос
/ 22 апреля 2009

Я бы хотел, чтобы ScoreChicksEngine сделал эту работу. Мои причины:

  1. Не зависит от того, знает ли пользователь / не забывает ли это делать.
  2. Могут быть случаи, когда это не нужно, например, ScoreChicksEngine решает, что его конфигурация не завершена.
  3. Если что-то должно быть сделано каждый раз, почему вызывающий абонент дублирует это везде?
  4. Упрощает работу пользователя, обеспечивая более компактную обработку, например:

    ScoreChicksEngine SCE = новый ScoreChicksEngine (command.ExecuteReader ());

1 голос
/ 22 апреля 2009

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

1 голос
/ 22 апреля 2009

Если у ScoreChicksEngine нет оснований предполагать, что читатель будет в определенном состоянии, я бы сам сделал всю работу. Что если вы забудете вызвать Read () перед инициализацией? Там нет никакого способа действительно проверить это, так что просто убедитесь, делая это в SCE.

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