2012-04-19 21 views
0

比較的大きなオブジェクト指向プログラムを構築しています。私はAerodynamicCalculatorというクラスを持っています。このクラスは数多くの計算を行い、結果をシステムに分配します。私の主な関心事は、私はそれにmorパラメータを追加すると、私のコンストラクタシグネチャがますます大きくなるということです。オブジェクト参照がコンストラクタを経由して渡される

以下に示すように、私は既にこのコンストラクタに9つのオブジェクト参照が渡されていますが、さらに7つ必要です。このオブジェクトを正しく作成していますか?私の理解は、コンストラクタに関連付けられたオブジェクト参照を渡し、オブジェクトの参照にclass'esローカル変数を割り当てることです。この場合、必要なすべてのオブジェクトでクラスを適切に初期化する唯一の方法は、それらをコンストラクタに渡すことです(非常に長い署名につながります)。

public AreodynamicCalculator(AircraftConfiguration config, AileronOne aOne, 
     AileronTwo aTwo, ElevatorOne eOne, ElevatorTwo eTwo, Rudder r, 
     Rudder rr, RateGyros rG) { 
    // ... 
} 

このアプローチに関するアドバイスは、事前に感謝の意を表します。

+0

さまざまな戦略が提案され、あなたが行く最善の方法かもしれません。しかし、これは、あなたのクラスがあまりにも多くをやろうとしているし、より小さな部分に分割する必要があるというサインである可能性があります。 –

+0

これは禁止されていません。これがその1つの方法です。他の方法もありますが、最終的にはシステムの特定のアーキテクチャーに至り、システムを作成する最善の方法を教えてくれるでしょう。この質問はおそらく広すぎるため閉鎖されるでしょう。 – Th0rndike

+0

このクラスは実際には5つの変数しか計算しませんが、これらの変数を7つのオブジェクトに分散する必要があります。どのように計算で使用される変数は、私は私の元の投稿で示したオブジェクトから抽出されます。だから、クラスdosntはゲッター、システム計算機、計算結果配布者としての役割を果たします。 –

答えて

6

前述のように、これはあなたのクラスがあまりにも多くのことをしているサインかもしれませんが、この問題によく使用される「解決策」があります。

ビルダーパターンはこの状況でよく使用されますが、引数が異なるコンストラクタが多数ある場合は非常に便利です。特にブールリテラルが使用されている場合は、引数の意味が明確になるためです。ここで

は、Builderパターンで、これが機能する方法は、このようなものです:

AreodynamicCalculator calc = AreodynamicCalculator.builder() 
    .config(theAircraftConfiguration) 
    .addAileron(aileronOne) 
    .addAileron(aileronTwo) 
    .addElevator(elevatorOne) 
    .addElevator(elevatorTwo) 
    .addRudder(rudderOne) 
    .addRudder(rudderTwo) 
    .build() 

内部的には、ビルダーは、これらすべてのフィールドを格納する、とbuild()が呼び出されたときには(今プライベート)コンストラクタを呼び出します。そのこれらのフィールドを取る:Builderパターンを使用する同様

class AreodynamicCalculator { 
    public static class Builder { 
     AircraftConfiguration config; 
     Aileron aileronOne; 
     Aileron aileronTwo; 
     Elevator elevatorOne; 
     Elevator elevatorTwo; 
     ... 

     public Builder config(AircraftConfiguration config) { 
      this.config = config; 
      return this; 
     } 

     public Builder addAileron(Aileron aileron) { 
      if (this.aileronOne == null) { 
       this.aileronOne = aileron; 
      } else { 
       this.aileronTwo = aileron; 
      } 
      return this; 
     } 

     // adders/setters for other fields. 

     public AreodynamicCalculator build() { 
      return new AreodynamicCalculator(config, aileronOne, aileronTwo ...); 
     } 
    } 

    // this is the AircraftConfiguration constructor, it's now private because 
    // the way to create AircraftConfiguration objects is via the builder 
    // 
    private AircraftConfiguration config, AileronOne aOne, AileronTwo aTwo, ElevatorOne eOne, ElevatorTwo eTwo, Rudder r, Rudder rr, RateGyros rG) { 
     /// assign fields 
    } 
} 
+0

ご協力いただきありがとうございます。それは有り難いです。パフォーマンスはありますか?もっと重要なのは、これを行うための安全上の理由ですか?パフォーマンスペナルティまでは –

+0

です。アプリをプロファイルする必要があります。作成されたオブジェクト(ビルダーオブジェクトとビルドオブジェクト)の代わりに2つのオブジェクト(おそらく同じサイズ)が作成され、ビルダーインスタンスが収集されます。安全性、あなたが何を意味するのか分かりません。ビルダーが完全に実装されていない(あまり設定されていない)場合は、例外がスローされるはずです(RuntimeExceptionサブクラスを使用します)。 – daveb

0

、あなたは春のような依存性注入フレームワークを使用することができ、davebの応答で提案されています。

+0

DIは異なるインプリメンテーションをインジェクトするのに役立ちます。コンストラクタに渡される参照が多すぎないようにするのは役立ちません。 – mrab

+0

は、コンストラクタインジェクションまたはメソッドインジェクション(プロパティセッターを使用)を使用しているかどうかによって異なります。両方とも春にすることができます。 –

関連する問題