Estoy tratando de adherirme al Principio Único de Responsabilidad (SRP) tanto como sea posible y me acostumbré a un determinado patrón (para el SRP en los métodos) que depende en gran medida de los delegados. Me gustaría saber si este enfoque es correcto o si existen problemas graves con él.
Por ejemplo, para verificar la entrada a un constructor, podría introducir el siguiente método (la entrada Stream
es aleatoria, podría ser cualquier cosa)
private void CheckInput(Stream stream)
{
if(stream == null)
{
throw new ArgumentNullException();
}
if(!stream.CanWrite)
{
throw new ArgumentException();
}
}
Este método (posiblemente) hace más de una cosa
- Comprueba las entradas
- Lanzar diferentes excepciones
Para cumplir con el SRP, por lo tanto, cambié la lógica a
private void CheckInput(Stream stream,
params (Predicate<Stream> predicate, Action action)[] inputCheckers)
{
foreach(var inputChecker in inputCheckers)
{
if(inputChecker.predicate(stream))
{
inputChecker.action();
}
}
}
Que supuestamente solo hace una cosa (¿lo hace?): verifique la entrada. Para la comprobación real de las entradas y el lanzamiento de las excepciones, he introducido métodos como
bool StreamIsNull(Stream s)
{
return s == null;
}
bool StreamIsReadonly(Stream s)
{
return !s.CanWrite;
}
void Throw<TException>() where TException : Exception, new()
{
throw new TException();
}
y puede llamar a CheckInput
like
CheckInput(stream,
(this.StreamIsNull, this.Throw<ArgumentNullException>),
(this.StreamIsReadonly, this.Throw<ArgumentException>))
¿Es esto mejor que la primera opción o introduzco una complejidad innecesaria? ¿Hay alguna manera de que pueda mejorar este patrón, si es viable?