У меня есть эта функция API:
public ResultEnum DoSomeAction(string a, string b, DateTime c, OtherEnum d,
string e, string f, out Guid code)
Мне это не нравится.Потому что порядок параметров становится излишне значимым.Становится сложнее добавлять новые поля.Труднее увидеть, что происходит вокруг.Сложнее реорганизовать метод в более мелкие части, потому что это создает дополнительные издержки, связанные с передачей всех параметров в подфункции.Код сложнее читать.
Я пришел к наиболее очевидной идее: иметь объект, инкапсулирующий данные, и передавать его вместо передачи каждого параметра один за другим.Вот что я придумал:
public class DoSomeActionParameters
{
public string A;
public string B;
public DateTime C;
public OtherEnum D;
public string E;
public string F;
}
Это уменьшило мою декларацию API до:
public ResultEnum DoSomeAction(DoSomeActionParameters parameters, out Guid code)
Хорошо.Выглядит очень невинно, но мы действительно внесли огромное изменение: мы ввели изменчивость.Потому что раньше мы фактически передавали анонимный неизменяемый объект: параметры функции в стеке.Теперь мы создали новый класс, который очень изменчив.Мы создали возможность манипулировать состоянием вызывающей стороны .Это отстой.Теперь я хочу, чтобы мой объект был неизменным, что мне делать?
public class DoSomeActionParameters
{
public string A { get; private set; }
public string B { get; private set; }
public DateTime C { get; private set; }
public OtherEnum D { get; private set; }
public string E { get; private set; }
public string F { get; private set; }
public DoSomeActionParameters(string a, string b, DateTime c, OtherEnum d,
string e, string f)
{
this.A = a;
this.B = b;
// ... tears erased the text here
}
}
Как видите, я фактически заново создал свою первоначальную проблему: слишком много параметров.Очевидно, что это не тот путь.Что я собираюсь делать?Последний вариант для достижения такой неизменности - это использование структуры «только для чтения», подобной этой:
public struct DoSomeActionParameters
{
public readonly string A;
public readonly string B;
public readonly DateTime C;
public readonly OtherEnum D;
public readonly string E;
public readonly string F;
}
, которая позволяет нам избегать конструкторов со слишком большим количеством параметров и достигать неизменности.На самом деле это решает все проблемы (упорядочение параметров и т. Д.).Тем не менее:
Вот тогда я запутался и решил написать этот вопрос: Какой самый простой способ в C # избежать проблемы «слишком большого количества параметров» без введения изменчивости?Можно ли использовать для этой цели только для чтения структуру и при этом не иметь плохой дизайн API?
УТОЧНЕНИЯ:
- Пожалуйста, предположите, что нарушения не существуетпринцип единой ответственности.В моем исходном случае функция просто записывает данные параметры в одну запись БД.
- Я не ищу конкретного решения для данной функции.Я ищу обобщенный подход к таким проблемам.Я особенно заинтересован в решении проблемы «слишком много параметров» без введения изменчивости или ужасного дизайна.
ОБНОВЛЕНИЕ
Ответы, представленные здесь, имеют различные преимущества/ недостатки.Поэтому я хотел бы преобразовать это в вики сообщества.Я думаю, что каждый ответ с примером кода и преимуществами и недостатками был бы хорошим руководством для подобных проблем в будущемЯ сейчас пытаюсь выяснить, как это сделать.