2010-10-18 2 views
3

У меня есть класс, который требует много аргументов для создания. Это своего рода аудиопроцессор, которому требуется частота дискретизации, разрешение выборки, количество каналов и т. Д. Большинство параметров имеют нормальные значения по умолчанию. И большинство из них должно быть установлено только в инициализаторе (конструкторе), потому что нет смысла менять их впоследствии. Я не хочу создавать гигантский инициализатор со всеми параметрами, потому что (1) он был бы огромным и, по существу, он только копировал переданные значения, не выполнял бы никакой реальной работы, и (2) пользователю приходилось указывать значения для всех параметры. Каков хороший способ решить эту проблему?Как инициализировать класс со многими аргументами конструктора?

Я пробовал писать геттеры и сеттеры для параметров. Это означает, что я не мог создать «реальный» блок обработки звука в конструкторе, так как тогда значения параметров неизвестны. Я должен был ввести новый метод (скажем prepareForWork), так что пользователи могут сделать что-то вроде:

AudioProcessor *box = [[AudioProcessor alloc] init]; 
[box setSampleRate:…]; 
[box setNumberOfChannels:…]; 
[box prepareForWork]; 
[box doSomeProcessing]; 

Это хорошо, потому что он не требует громоздкого конструктора. Кроме того, значения по умолчанию задаются в инициализаторе, что означает, что я могу взять новый экземпляр AudioProcessor, и он все равно может выполнить некоторую работу. Оборотная сторона состоит в том, что (1) существует дополнительный метод, который должен быть вызван до того, как экземпляр сможет выполнить какую-либо реальную работу, и (2) класс должен отказаться от изменения каких-либо параметров после вызова prepareForWork. Охрана обоих этих инвариантов потребовала бы какой-то шаблонный код, который мне не нравится.

Я думал, что я мог бы создать специальный класс «Preset», который будет выглядеть следующим образом:

@interface SoundConfig : NSObject { 
    NSUInteger numberOfChannels; 
    NSUInteger sampleResolution; 
    float sampleRate; 
} 

И тогда требуется экземпляр этого класса в AudioProcessor инициализаторе:

@interface AudioProcessor : NSObject {…} 
- (id) initWithConfig: (SoundConfig*) config; 

значения по умолчанию был бы установлен в инициализаторе SoundConfig, конструктор AudioProcessor был бы простым и не было бы никаких инвариантов, чтобы следить за ними вручную.

Другой подход, о котором я думал, был своего рода классом AudioProcessorBuilder. Вы бы создали экземпляр этого объекта, установили параметры аудио через аксессуры, а затем, наконец, он построил для вас экземпляр AudioProcessor, установив все свойства через непубличные сеттеры, чтобы вы не могли впоследствии их изменить (и разбить инвариант) ,

Теперь, когда я пишу это, я поддерживаю подход SoundConfig. Как вы решаете это, есть ли лучший подход?

ответ

4

Посмотрите, как осуществляется NSURLConnection и used. Он использует объект NSURLRequest для его параметризации, аналогично тому, как объект SoundConfig параметризует объект AudioProcessor.

+0

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

1

Обычно, когда у вас есть класс со многими параметрами конструктора, особенно если некоторые или большинство из них являются необязательными, вы хотите использовать Builder Pattern. Смешная вещь, я не могу найти примеры для объектива-c, поэтому я не уверен, что ее можно было бы легко применить здесь ...

2

Обычный способ - это создать гигантский инициализатор вместе с несколькими инициализаторами для нестандартных значений или наборов значений.

-initWithSampleRate:numberOfChannels:sampleResolution: 
-initWithSampleRate:sampleResolution: 
-initWithSampleRate:numberOfChannels: 
-initWithNumberOfChannels:sampleResolution: 
-initWithNumberOfChannels: 
-initWithSampleResolution: 
-initWithSampleRate: 
-init 

Но подход SoundConfig выглядит проще.

+1

Если вы собираетесь использовать параметр SoundConfig, который я согласен, то лучше использовать NSDictionary. NSDictionary, по-видимому, является способом Apple для инициализации объектов с большим количеством произвольных параметров. – JeremyP

+0

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

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