Я намагаюся максимально дотримуватися Принципу єдиної відповідальності (СРП) і звик до певної моделі (для СРП щодо методів), сильно покладаючись на делегатів. Мені хотілося б знати, чи є такий підхід обгрунтованим чи є якісь серйозні проблеми з ним.
Наприклад, щоб перевірити вхід до конструктора, я міг би ввести наступний метод ( 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
все ще робиться кілька речей: це ітерація над масивом, і виклик функції предиката та виклик функції дії. Хіба це не є порушенням СРП?