J'ai une classe qui prend de nombreux arguments à créer. C'est une sorte de processeur audio qui a besoin d'une fréquence d'échantillonnage, d'une résolution d'échantillonnage, d'un nombre de canaux, etc. La plupart des paramètres ont des valeurs par défaut saines. Et la plupart d'entre eux ne devraient être configurables que dans l'initialiseur (constructeur), car cela n'a aucun sens de les changer par la suite. Je ne veux pas créer un initialiseur gargantuesque avec tous les paramètres car (1) ce serait énorme et essentiellement il ne ferait que copier les valeurs passées, ne faisant aucun travail réel, et (2) l'utilisateur devrait spécifier des valeurs pour tous les paramètres. Quel est un bon moyen de résoudre cela?Comment initialiser une classe avec de nombreux arguments constructeur?
J'ai essayé d'écrire des getters et des setters pour les params. Cela signifie que je ne pouvais pas créer la "vraie" unité de traitement audio dans le constructeur, puisque les valeurs des paramètres ne sont pas connues à ce moment-là. Je devais introduire une nouvelle méthode (par exemple prepareForWork
) afin que les utilisateurs peuvent faire quelque chose comme:
AudioProcessor *box = [[AudioProcessor alloc] init];
[box setSampleRate:…];
[box setNumberOfChannels:…];
[box prepareForWork];
[box doSomeProcessing];
C'est agréable car il ne nécessite pas de constructeur difficile à manier. De plus, les valeurs par défaut sont définies dans l'initialiseur, ce qui signifie que je peux prendre une nouvelle instance AudioProcessor
et il pourrait encore faire un peu de travail. Le revers de la médaille est que (1) il y a une méthode supplémentaire qui doit être appelée avant que l'instance puisse faire un travail réel et (2) la classe devrait refuser de changer l'un des paramètres après que prepareForWork
ait été appelée. Garder ces deux invariants prendrait un code standard que je n'aime pas.
Je pensais que je pouvais créer une classe spéciale « preset » qui ressemblerait à ceci:
@interface SoundConfig : NSObject {
NSUInteger numberOfChannels;
NSUInteger sampleResolution;
float sampleRate;
}
Et puis besoin d'une instance de cette classe dans le AudioProcessor
initialiseur:
@interface AudioProcessor : NSObject {…}
- (id) initWithConfig: (SoundConfig*) config;
Les valeurs par défaut serait défini dans l'initialiseur SoundConfig
, le constructeur AudioProcessor
serait simple et il n'y aurait pas d'invariants à continuer à regarder à la main.
Une autre approche que je pensais était une sorte de classe AudioProcessorBuilder
. Vous créez une instance de ceci, définissez les paramètres audio à travers les accesseurs et enfin, vous construisez une instance AudioProcessor
pour vous, définissant toutes les propriétés via un setters non public de sorte que vous ne puissiez pas les changer plus tard (et rompez l'invariant) .
Maintenant que j'écris cela, je suis favorable à l'approche SoundConfig
. Comment résolvez-vous cela, y a-t-il une meilleure approche?
Aurait été bien si vous pouviez un exemple d'utilisation.Le lien fourni n'est plus disponible. –