web-dev-qa-db-ja.com

大規模なデータクラスでコンストラクタを処理する方法

数回、私はあなたが単に大量のデータを含むある種の設定クラスを持っている状況に遭遇しました。多くの場合、これらのクラスは、少なくともほとんどのデータがないと単純に無効になります。

しかし、このようなコンストラクタ:

public dataclass (int v1, int v2, int v3, int v4,
      string v5, double v6, string v7, int v8, 
      Internalclass v9, string v10,
      double v11, double v12, int v13, int v14)
{
   this.v1=v1;
   this.v2=v2;
   ...
   this.v14=v14; 
}

それは良いコード実践ではないように感じます。これで、これらの変数のいくつかをグループ化しようとすることができましたが、これらの変数は、データクラスのコンテキストでのみ意味をなすことがよくあります。では、そのようなデータクラスを設計する良い方法は何でしょうか。

8
Thijser

ビルダーパターン を探しています。

基本的には、構築用のパラメーターを設定できるセッターを備えたオブジェクトと、探しているオブジェクトを作成するcreateResult()メソッドです(または、有効でない場合は失敗します)。

これを使用して、プロパティのデフォルトを格納し、それらのいくつかを単一のセッターにグループ化できます。

DataClassBuilder builder = new DataClassBuilder();

builder.setV1(v1);
builder.setV3(v3);
builder.setV4(v4);
builder.setV5AndV6(v5, v6);
//...

DataClass data = builder.createResult();
13
ratchet freak

これらすべてのパラメーターが実際に必要ですか? 「データクラス」とは、ドメインモデルビューモデル、またはデータ転送オブジェクトを意味しますか?単純な "データクラス"にこのような大量の引数のリストを要求すると、コードの臭いが次のいずれかを伝えるように感じ始めます。

  1. このクラスはあまりにも多くを行っており、その作業の多くは、依存関係として渡される他のクラスに委任されるべきです

  2. すべてが必要なわけではありません。データクラスのオプション値は、コンストラクタを介して渡してはなりません

ここでの質問は、「コンストラクターの引数の大きなリストをどのように処理するか」ではなく、「コンストラクターにパラメーターを必要としないように、オブジェクトモデルをリファクタリングするにはどうすればよいか」ではないと思います。

Builderパターンは問題を「修正」しますが、別の解決策を必要とするより大きな問題に包帯を巻いていると思います。

5
Greg Burghardt

パラメータがオプションの場合、Builderパターンは本当に便利です。ただし、ビルダーのパターンが混乱する場合があります。多くの場所でBuilderを使用する場合、新しいパラメーターを追加するときは、コンパイル時のチェックがないため、すべての場所に追加することを忘れないようにする必要があります。 。

パラメータがオプションでない場合は、Buildメソッドを呼び出すために、現時点ですべてが設定されていることを確認する必要があります。

私は別の解決策を提案したいと思います Introduce Parameter Object リファクタリング。

アイデアは、いくつかのロジックによってパラメーター(可能な場合)をグループ化することです。次に、thisコンストラクターに含まれるパラメーターが少なくなり、おそらく3から4の「パラメータークラス」が増えます。これにより問題が別の場所に移動すると主張することもできますが、これらのパラメーターオブジェクトを作成する方法に柔軟性がもたらされます。

「パラメータオブジェクト」の1つはハードコードされたファクトリを介して作成でき、もう1つは構成ファイルなどから取得できます。

このようにして、懸念の分離を改善します!

0
IEatBagels