6

関数内の長いパラメーターリストに対する自然な嫌悪感を開発しました。これはある程度良いことですが、「手動インライン化」のために、コードの重複や途方もなく長い関数と比較して、長いパラメータリストが2つの悪のうちの少ない方である場合があります。少なくともこれらの怪物のいくつかを人間が読めるようにするための良い方法は何ですか?例えば:

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

これは読みやすさの尺度では高得点ではありませんが、多くの場合、4つのパラメーターはかなり妥当です。

4

5 に答える 5

10

このような状況では、次のようにフォーマットする傾向があります。

SomeClass[string] someFunction(
    SomeClass!(TemplateParam) foo, 
    string[][string] someAA,
    uint[] dataToProcess,
    SomeEnumType flag
)
{
    // Do stuff.
}
于 2010-01-28T17:48:55.917 に答える
3
  • 読みやすくするために-各引数を新しい行に配置します
  • 使いやすさとAPI設計の改善のために、関連する引数を新しいクラスにグループ化して、引数の数を減らします。
于 2010-01-28T18:01:41.707 に答える
1

幅広い関数宣言/呼び出しを回避するために、(主に内部)クラス(または構造体)のパラメーターを再グループ化します

于 2010-01-28T17:51:38.340 に答える
1

パラメータオブジェクトを導入できます。

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は、クラスがその外部クラスに関連付けられていないこと、つまり、そのフィールドにアクセス/変更できないことを意味します。

于 2010-01-28T18:13:38.337 に答える
0

各パラメーターに改行を入れるだけで、アーロンの返信が好きです。

それが多すぎる場合は、少しリファクタリングする時が来ました。

それでも多くのパラメータが必要な場合は、代わりにプロパティをラップするクラスを渡すように切り替えてください。次に、署名を台無しにすることなく、デフォルトのパラメータをメソッドに簡単に追加できるという追加のボーナスが得られます。

于 2010-01-28T17:54:40.617 に答える