I have a class that takes a lot of arguments to create. This is a kind of audio processor that needs a sampling rate, sample resolution, number of channels, etc. Most parameters have normal default values. And most of them should be installed only in the initializer (constructor), because there is no point in changing them later. I do not want to create a giant initializer with all parameters, because (1) it would be huge and, in essence, it would only copy the transferred values, would not do any real work, and (2) the user would have to specify values for all parameters. What is a good way to solve this problem?
I tried to write getters and setters for parameters. This means that I could not create a "real" block of sound processing in the constructor, since then the parameter values are unknown. I had to introduce a new method (say prepareForWork) so that users could do something like:
AudioProcessor *box = [[AudioProcessor alloc] init];
[box setSampleRate:…];
[box setNumberOfChannels:…];
[box prepareForWork];
[box doSomeProcessing];
This is good because it does not require a cumbersome constructor. Also, the default values are set in the initializer, which means that I can take a fresh instance AudioProcessor, and it can still work. The flip side is that (1) there is an additional method that must be called before the instance can do any real work, and (2) the class must refuse to change any parameters after the call prepareForWork. Protecting both of these invariants would bring some sort of boilerplate code that I don't like.
I thought I could create a special “predefined” class that would look like this:
@interface SoundConfig : NSObject {
NSUInteger numberOfChannels;
NSUInteger sampleResolution;
float sampleRate;
}
And then an instance of this class is required in the initializer AudioProcessor:
@interface AudioProcessor : NSObject {…}
- (id) initWithConfig: (SoundConfig*) config;
SoundConfig, AudioProcessor , .
, , AudioProcessorBuilder. , , , , AudioProcessor , , ( ).
, , SoundConfig. , ?