Sto cercando di aderire il più possibile al principio della responsabilità singola (SRP) e mi sono abituato a un certo modello (per SRP sui metodi) facendo molto affidamento sui delegati. Mi piacerebbe sapere se questo approccio è valido o se ci sono problemi gravi con esso.
Ad esempio, per controllare l'input di un costruttore, potrei introdurre il seguente metodo (l' Stream
input è casuale, potrebbe essere qualsiasi cosa)
private void CheckInput(Stream stream)
{
if(stream == null)
{
throw new ArgumentNullException();
}
if(!stream.CanWrite)
{
throw new ArgumentException();
}
}
Questo metodo (probabilmente) fa più di una cosa
- Controlla gli ingressi
- Genera diverse eccezioni
Per aderire all'SRP ho quindi modificato la logica in
private void CheckInput(Stream stream,
params (Predicate<Stream> predicate, Action action)[] inputCheckers)
{
foreach(var inputChecker in inputCheckers)
{
if(inputChecker.predicate(stream))
{
inputChecker.action();
}
}
}
Che presumibilmente fa solo una cosa (vero?): Controlla l'input. Per l'effettivo controllo degli input e il lancio delle eccezioni ho introdotto metodi simili
bool StreamIsNull(Stream s)
{
return s == null;
}
bool StreamIsReadonly(Stream s)
{
return !s.CanWrite;
}
void Throw<TException>() where TException : Exception, new()
{
throw new TException();
}
e può chiamare CheckInput
come
CheckInput(stream,
(this.StreamIsNull, this.Throw<ArgumentNullException>),
(this.StreamIsReadonly, this.Throw<ArgumentException>))
È forse qualcosa di meglio della prima opzione o introduco complessità non necessarie? Esiste un modo in cui posso ancora migliorare questo modello, se possibile?
CheckInput
sta ancora facendo più cose: sta iterando su un array e chiamando una funzione predicata e chiamando una funzione action. Non è quindi una violazione dell'SRP?