Должны ли все мои аргументы быть в конструкторе? - PullRequest
3 голосов
/ 24 августа 2011

У меня есть класс StreamCopyOperation, который предоставляет мне такие вещи, как средняя скорость операции копирования и другую информацию.

Теперь у меня есть конструктор, который выглядит как

public StreamCopyOperation(Stream source, Stream target, int bufferSize, int updateInterval)
{
    //Initialize values
}

и метод

public void CopyStream()
{
    //Copy the streams, send the progress updates, etc...
}

Теперь я не знаю, должны ли все аргументы быть в конструкторе или потоки должны быть переданы в метод следующим образом:

public void CopyStream(Stream source, Stream target)
{
    //Copy the streams, send the progress updates, etc...
}

иконструктор получает только размер буфера и пройденный интервал обновления.Или, может быть, все должно быть в методе CopyStream.

Есть ли что-то вроде лучшей практики или это просто дизайнерское решение?

Ответы [ 7 ]

4 голосов
/ 24 августа 2011

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

Если это класс с однократным использованием, тогда, возможно, все аргументы должны быть переданы в конструктор, а затем вы устанавливаете любые другие свойства и затем вызываете CopyStream (без аргументов).

Но, если вы ожидаете изменения параметров потока, не передавайте их в конструктор и передавайте значения в метод CopyStream.

Наконец, если это действительно класс с однократным использованием, то, возможно, вам следует рассмотреть класс как класс static и CopyStream как статический - экономит вам строку кода и делает класс больше вспомогательного типа класса.

Надеюсь, это поможет!

2 голосов
/ 24 августа 2011

На мой взгляд, это будет зависеть от времени жизни объекта StreamCopyOperation ...

В частности, поскольку потоковые объекты обычно (всегда?) Одноразовые и привязаны к какому-либо системному ресурсу, я хотел бы хранить их как можно меньше, чтобы подумать о параметризованном подходе.

Если StreamCopyOperation связан только с временем жизни самих потоков, тогда подходит первый метод.

Но если вы хотите сохранить объект операции дольше (например, потому что он подключен к пользовательскому интерфейсу), тогда я бы пошел с подходом параметризованных функций и обратился к более статическому «классу помощника».

1 голос
/ 24 августа 2011

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

0 голосов
/ 24 августа 2011

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

Конечно, вы могли бы предоставить удобные перегрузки конструктора (или необязательный аргумент), чтобы было проще использовать ваш класс в большем количестве ситуаций (но их можно отложить до «конструирования методов», например, TimeSpan.FromMinutes(5)). Но помните, что конструктор предназначен для простого создания и инициализации вашего типа и всех его подсистем, чтобы он находился в пригодном для использования и согласованном состоянии и был готов выполнять ставки пользователя.

Исключением, конечно же, являются неизменяемые типы, где необходимо указывать все параметры во время построения. Обычно неизменяемые типы довольно просты, так что это не проблема. Если они более сложны, а число параметров конструктора выходит из-под контроля, вы можете использовать изменяемый объект «инициализатор-спецификатор», который содержит все различные конфигурации инициализации неизменяемого объекта, но с ним проще работать, поскольку он имеет изменчивые свойства.

0 голосов
/ 24 августа 2011

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

private const int DEF_BUFFER = 100;
private const int DEF_INTERVAL = 10;

public StreamCopyOperation(Stream source, Stream target)
{
   //Initialize values
   this.BufferSize = DEF_BUFFER;
   this.UpdateInterval = DEF_INTERVAL;
} 

public int BufferSize { get; set;} // or use a private member inside, if needed

public int UpdateInterval { get; set;} // or use a private member inside, if needed
0 голосов
/ 24 августа 2011

Я бы в значительной степени посчитал это дизайнерским решением.

Если один экземпляр CopyStreamOperator не будет повторно использоваться для нескольких источников и / или целей, я, вероятно, передам все необходимые значения в конструкторесоздать объект, который знает все, что ему нужно знать.Затем входные значения могут быть проверены, чтобы убедиться, что ваш оператор никогда не находится в недопустимом состоянии.

Затем переименуйте метод CopyStream() без параметров в Run() или Execute().

0 голосов
/ 24 августа 2011

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

надеюсь, эта помощь.

...