Как сделать длинные списки параметров читабельными? - PullRequest
4 голосов
/ 28 января 2010

Я разработал естественное отвращение к длинным спискам параметров в функциях. Хотя это в некоторой степени хорошо, иногда длинные списки параметров являются меньшим из двух зол по сравнению с дублированием кода или смехотворно длинными функциями из-за «ручного встраивания». Какой хороший способ хотя бы сделать некоторые из этих чудовищ удобочитаемыми? Например:

SomeClass[string] someFunction(SomeClass!(TemplateParam) foo, 
    string[][string] someAA, uint[] dataToProcess, SomeEnumType flag) {
    // Do stuff.
}

Это не очень высокий показатель по шкале читабельности, но во многих случаях достаточно четырех параметров.

Ответы [ 5 ]

7 голосов
/ 28 января 2010

Для такой ситуации я склонен форматировать это так:

SomeClass[string] someFunction(
    SomeClass!(TemplateParam) foo, 
    string[][string] someAA,
    uint[] dataToProcess,
    SomeEnumType flag
)
{
    // Do stuff.
}
2 голосов
/ 28 января 2010
  • для удобства чтения - поместите каждый аргумент в новую строку
  • ради удобства использования и лучшего описания API - группируйте связанные аргументы в новые классы, таким образом сокращая количество аргументов.
1 голос
/ 28 января 2010

Вы можете ввести параметр объекта:

class ParameterObject {
    public final SomeClass!(TemplateParam) foo; 
    public final string[][string] someAA;
    public final uint[] dataToProcess;
    public final SomeEnumType flag;

    private ParameterObject(
       SomeClass!(TemplateParam) foo, 
       string[][string] someAA,
       uint[] dataToProcess,
       SomeEnumType flag) {
       this.foo = foo;
       this.someAA = someAA;
       this.dataToProcess = dataToProcess;
       this.flag = flag;
    }

    private static class Builder {
        public SomeClass!(TemplateParam) foo; 
        public string[][string] someAA;
        public uint[] dataToProcess;
        public SomeEnumType flag;

        public Builder foo(SomeClass!(TemplateParam) foo) {
            this.foo = foo;
            return this;
        }

        public Builder someAA(string[][string] someAA) {
            this.someAA = someAA;
            return this;
        }

        public Builder dataToProcess(uint[] dataToProcess) {
            this.dataToProcess = dataToProcess;
            return this;
        }

        public Builder flag(SomeEnumType flag) {
            this.flag = flag;
            return this;
        }

        public ParameterObject build() {
            if (null == foo) throw Exception("init foo!");
            if (null == someAA) throw Exception("init someAA!");
            if (null == dataToProcess) throw Exception("init dataToProcess!");
            if (null == flag) throw Exception("init flag!");
            return new ParameterObject(foo, someAA, dataToProcess, flag);
        }
    }
}

Теперь ваш звонок будет выглядеть, например:

SomeClass[string] myValue = 
   someFunction(
      new ParameterObject.Build().
          foo(myFoo).
          someAA(myAA).
          dataToProcess(myData).
          flag(false).
          build()
   );

Гораздо проще иметь дело с подобными случаями в языках, которые позволяют создавать встроенные карты:

someFunction(
    Map.new(
        foo => myFoo,
        someAA => myAA,
        dataToProcess => myData,
        flag => false
    )

Квалификатор final означает, что поле может быть установлено только из конструктора класса. Квалификатор static перед классом означает, что класс не привязан к своему внешнему классу, то есть не может получить доступ / изменить его поля.

1 голос
/ 28 января 2010

Я перегруппировываю параметры в (в основном внутренний) класс (или структуру), чтобы избежать широкого объявления / вызова функции

0 голосов
/ 28 января 2010

Мне нравится ответ Аарона, просто дается новая строка для каждого параметра.

Когда это становится слишком много, тогда пришло время немного реорганизовать.

Если вам все еще нужно столько параметров, переключитесь на передачу в класс, который обернет ваши свойства. Затем вы получаете дополнительный бонус за простое добавление параметров по умолчанию и к вашему методу, не портя свою подпись.

...