2009-04-21 2 views
2

Скажите, что у вас есть объект, который, например, мы будем называть ScoreHotChicksEngine. И скажите, что конструктор ScoreHotChicksEngine ожидает, что будет передан идентификатор IDataReader, содержащий значения свойств, относящиеся к, соответственно, для подсчета очков Hot Chicks для Lonely Geeks.Полностью арбитр C# Вопрос

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(); 
+1

Если работает ScoreHotChicksEngine, вы продаете его? –

+0

Конечно, потому что, хотя я больше не был бы единственным человеком с ScoreHotChickEngine, у меня было бы так много денег, что мне не понадобилось бы соревноваться. –

ответ

3

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

6

Вы не должны думать о развязке сбора данных от алгоритма и использовать раствор связующего между ними (адаптером итератора, например)? Только мои 0,02 доллара.

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

+1

Я абсолютно согласен с @dirkgently. ScoreChicksEngine не должен заботиться или даже знать, что он получает свои данные из IDataReader. Развязка - это путь сюда. –

1

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

1

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

1

У меня бы был ScoreChicksEngine, выполнив эту работу. Мои причины:

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

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

1

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

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

В самом деле, что я сделал в прошлом создается класс-оболочку вокруг считывания данных (с помощью методов, как GetInt32 (имя), GetString («имя») и т. д.

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

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

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

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

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

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

И это, вероятно, указывает на мысль о развязке, как было предложено ранее.

1

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

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

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

Смежные вопросы