Я стараюсь максимально придерживаться принципа единой ответственности (SRP) и привык к определенной схеме (для SRP по методам), в значительной степени полагаясь на делегатов. Я хотел бы знать, является ли этот подход обоснованным или есть ли какие-либо серьезные проблемы с ним.
Например, чтобы проверить ввод в конструктор, я мог бы ввести следующий метод ( Stream
ввод случайный, может быть любым)
private void CheckInput(Stream stream)
{
if(stream == null)
{
throw new ArgumentNullException();
}
if(!stream.CanWrite)
{
throw new ArgumentException();
}
}
Этот метод (возможно) делает больше чем одно
- Проверьте входы
- Бросай разные исключения
Чтобы придерживаться SRP, я изменил логику
private void CheckInput(Stream stream,
params (Predicate<Stream> predicate, Action action)[] inputCheckers)
{
foreach(var inputChecker in inputCheckers)
{
if(inputChecker.predicate(stream))
{
inputChecker.action();
}
}
}
Который предположительно делает только одну вещь (делает это?): Проверьте вход. Для фактической проверки входных данных и выдачи исключений я ввел такие методы, как
bool StreamIsNull(Stream s)
{
return s == null;
}
bool StreamIsReadonly(Stream s)
{
return !s.CanWrite;
}
void Throw<TException>() where TException : Exception, new()
{
throw new TException();
}
и может звонить CheckInput
как
CheckInput(stream,
(this.StreamIsNull, this.Throw<ArgumentNullException>),
(this.StreamIsReadonly, this.Throw<ArgumentException>))
Это вообще лучше, чем первый вариант, или я ввел ненужную сложность? Можно ли как-то улучшить этот паттерн, если он вообще жизнеспособен?
CheckInput
все еще делает несколько вещей: это итерация по массиву и вызов функции предиката и вызов функции действия. Разве это не является нарушением ПСП?