Ich versuche, mich so weit wie möglich an das Prinzip der einheitlichen Verantwortung (Single Responsibility Principle, SRP) zu halten, und habe mich an ein bestimmtes Muster (für die SRP-Methode) gewöhnt, das sich stark auf Delegierte stützt. Ich würde gerne wissen, ob dieser Ansatz richtig ist oder ob es ernsthafte Probleme damit gibt.
Um beispielsweise die Eingabe in einen Konstruktor zu überprüfen, könnte ich die folgende Methode einführen (die Stream
Eingabe ist zufällig, kann beliebig sein).
private void CheckInput(Stream stream)
{
if(stream == null)
{
throw new ArgumentNullException();
}
if(!stream.CanWrite)
{
throw new ArgumentException();
}
}
Diese Methode macht (wohl) mehr als eine Sache
- Überprüfen Sie die Eingaben
- Wirf verschiedene Ausnahmen
Zur Einhaltung der SRP habe ich daher die Logik auf geändert
private void CheckInput(Stream stream,
params (Predicate<Stream> predicate, Action action)[] inputCheckers)
{
foreach(var inputChecker in inputCheckers)
{
if(inputChecker.predicate(stream))
{
inputChecker.action();
}
}
}
Was angeblich nur eins tut (oder?): Überprüfen Sie die Eingabe. Für die eigentliche Überprüfung der Eingaben und das Auslösen der Ausnahmen habe ich Methoden wie eingeführt
bool StreamIsNull(Stream s)
{
return s == null;
}
bool StreamIsReadonly(Stream s)
{
return !s.CanWrite;
}
void Throw<TException>() where TException : Exception, new()
{
throw new TException();
}
und kann CheckInput
gerne anrufen
CheckInput(stream,
(this.StreamIsNull, this.Throw<ArgumentNullException>),
(this.StreamIsReadonly, this.Throw<ArgumentException>))
Ist das besser als die erste Option überhaupt, oder füge ich unnötige Komplexität hinzu? Gibt es eine Möglichkeit, dieses Muster noch zu verbessern, wenn es überhaupt machbar ist?
CheckInput
sich mehrere Dinge noch zu tun: Es ist sowohl Iteration über ein Array und ein Prädikat Funktion aufrufen und eine Aktion Funktion aufrufen. Ist das dann kein Verstoß gegen die SRP?