开发者

How to make long parameter lists readable?

开发者 https://www.devze.com 2022-12-18 14:08 出处:网络
I\'ve developed a natural aversion to long parameter lists in functions.While this is to some extent a good thing, sometimes long parameter lists are the lesser of two evils compared to c开发者_C百科o

I've developed a natural aversion to long parameter lists in functions. While this is to some extent a good thing, sometimes long parameter lists are the lesser of two evils compared to c开发者_C百科ode duplication or ridiculously long functions due to "manual inlining". What's a good way to at least make some of these monstrosities human-readable? For example:

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

This doesn't score high on the readability scale, but four parameters is pretty reasonable in a lot of cases.


For this kind of situation, I tend to format it like this:

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


  • for the sake of readability - put each argument on new line
  • for the sake of usability and better API desgin - group related arguments into new classes, thus shortening the number of arguments.


I regroup parameters in an (mostly inner) class (or a struct) to avoid wide function declaration/call


You can introduce parameter object:

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);
        }
    }
}

Now, your call would look for example:

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

It's much easier to deal with similar cases in languages which allow creation of inline maps:

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

Qualifier final means that a field can be set only from class's constructor. Qualifier static in front of a class means that the class is not tied to it's outer class, i.e. can't access/mutate its fields.


I like Aaron's reply, just giving a newline for each param.

When that gets to be too much, then it's time to refactor a bit.

If you still need that many parameters, switch to passing in a class that wraps your properties instead. Then you get the added bonus of easily adding defaulted parameters to your method as well, without screwing up your signature.

0

精彩评论

暂无评论...
验证码 换一张
取 消