2010-12-11 3 views
27

Constructorとユーザ定義のInitialize()メソッドの違いは基本的にわかります。Initialize()vsコンストラクタ()メソッド、オブジェクト作成時の適切な使用

私の質問は、オブジェクト作成のための最良の設計方法に焦点を当てています。すべてInitialize()コードをConstructor()に入れてもかまいません(すべてのウォームアップコードをInitializeメソッドに移動し、このメソッドをConstructorから呼び出します)。

現在、新しいクラスを設計する際に、constructor()内に新しいインスタンスを作成し、他のウォームアップコードをInitialize()メソッドに移動します。

あなたの意見にはどのようなトレードオフがありますか?私は考慮すべき複数の側面があると思い

答えて

23

  • は、コンストラクタは、それが使用可能な状態でありますように、オブジェクトを初期化する必要があります。

  • コンストラクタはオブジェクトの初期化のみを行い、重い作業は行わないでください。

  • コンストラクタは、仮想メンバーまたは外部コードを直接的または間接的に呼び出すべきではありません。

ほとんどの場合、Initializeメソッドは必要ありません。

初期化でオブジェクトを使用可能な状態(たとえば、重い作業を実行する必要があるか、仮想メンバまたは外部を呼び出す必要がある)以上になる場合は、Initializeメソッドを使用することをお勧めします。

+0

過去には、ファクトリパターンのようにオブジェクトを直接インスタンス化していないときに、コンストラクタに渡って 'initialize()'メソッドを使うようになってきました。これは適切な考慮事項だと思いますか? – Ray

3

私は自分自身の考えを分かち合いたいと思っていました。 「理想的」

  • コンストラクタのみすなわち、オブジェクトの状態を設定する必要がありますいくつか:私の意見では

this.member = member;

これはIoCを、継承、テストだけの素敵なにおいがするとうまく果たしています。重い物を持ち上げるで

  • パス:

    しかし重い物を持ち上げるには、時々私は何をしようとしてきたことはあるので必要です。

これは、初期化コードを別のクラスに抽象化して渡すことを意味します。これは通常、重い持ち上げが実際にオブジェクトの責任ではない場合があるため、実際にリファクタリングを行うことでより良いコードになります。

これが不可能で、使用前にクラスの状態を初期化する必要がある場合は、initialseメソッドを追加してください。これはあなたのコードに時間的依存関係を追加んが、IoCコンテナを使用している場合、これは特に、必ずしも悪いことではありません。

セイCarEngineDrivingAssistComputerを必要とし、DrivingAssistComputerニーズ重い初期化を行うために、すなわち、すべてのパラメータ、気象条件のチェックをロードし、注目すべきもう一つのことは、CarEngineが直接DrivingAssistComputerと対話していないことです。実際には、エンジンはバックグラウンドで何かをやっている(どこかの状態を変える)ことなく、正しく動作しないかもしれません。我々はのIoCを使用している場合、我々は持っている:

// Without initialise (i.e. initialisation done in computer constructor) 
public CarEngine(FuelInjectors injectors, DrivingAssistComputer computer) { 
    this.injectors = injectors; 
    // No need to reference computer as we dont really interact with it. 
} 

... 

をそれでは、私たちはここに持っていることは依存としてcomputerをマークするが、実際にそれを使用していないコンストラクタ引数です。だから、これは醜いですが、初期化メソッドを追加することができます:

public CarEngine(FuelInjectors injectors, DrivingAssistComputer computer) { 
    this.injectors = injectors; 
    // This ofcourse could also be moved to CarEngine.Initialse 
    computer.Initialise(); 
} 

... 

まだ、凝集クラスが、少なくとも我々は直接コンストラクタの外でそれと相互作用していなくても、私たちはコンピュータに依存していることを知っています。

CarEngine CreateEngine(FuelInjectors injectors) { 
    new DrivingAssistComputer().Initialise(); 
    return new CarEngine(injectors); 
} 

... 

は、しかし、私は工場を見つけて、IoCのは、ちょうどので、私は目のオプションのために行くだろう行列を混乱させる:

別のオプションのofcourseのはありませんCarEngineFactoryを持つことです。

これに関するいくつかの考えを聞いて欲しいです。

編集1: 私が上記に欠けていたもう1つの選択肢は、Initializeメソッドを持っていますが、この呼び出しをIoC初期化モジュールに移動していることです。したがって、作成と初期化はまだまだカプセル化されています。

+0

+1は「重い吊り上げ」のために - これは私には意味がある –

関連する問題