http://martinfowler.com/bliki/ConstructorInitialization.html

2006/2/7

新しいオブジェクトを初期化する2つの方法のひとつ。 もうひとつの方法はSetterInitializationである。

コンストラクタによる初期化を使う場合は、 生成メソッドに必要なコラボレータをすべて渡して、 常に妥当な状態のオブジェクトを作るようにしなければならない。

# ruby
mf = Person.new('martin', 'fowler', 
                ['Turners Oyster Bar', 'Square and Compass'])

これにより、すぐに使える整った状態のオブジェクトを常に得ることができる。 これはまたコンパクトな方法でもある。 ワンライナーでオブジェクトを生成できるからだ。 オブジェクトに行わせたいことが1つだけだったら、 これに続けて何かをアサインしたりメソッドを呼び出したりすれば、 1行で済むことになる。何行もだらだら書く必要はない。

コンストラクタで必要なコラボレータを宣言することで、 明示的にそれが分かるし、クラスがどのように扱えばよいのかも簡単に分かる。 必要なコラボレータの組ごとにコンストラクタを設ける必要があるかもしれない。 頻繁に必要となるコラボレータをコンストラクタに含めてしまうのも便利だ。

この方法だと、イミュータブルな属性と更新可能な属性を区別することができる。 イミュータブルな属性はコンストラクタで初期化されるため、セッターメソッドが存在しないのである。

私は最初にコンストラクタによる初期化を考える。 それが難しい場合は、セッターによる初期化を行う。 ただし、コンストラクタによる初期化がベストな方法だ。

よくある疑問

オブジェクトを作成する正しい組み合わせがいくつもあったらどうするの?

この方法を使ったばっかりに、コンストラクタが一億と二千個もあるから困ってるっていう話をよく耳にする。 たいていの場合、これはあまり問題にはならない。ごくごく稀なケースである。 その場合は、本当に必要なコラボレータだけを配置すればよいだろう。 その他の組み合わせは滅多にない。

コンストラクタに渡すコラボレータがたくさんあったらどうするの?

コンストラクタのパラメータがたくさんあったら、その他のパラメータと同じく、CodeSmellだ。 この状況を目にしたら、パラメータをDataClumpsだと見なして、オブジェクトに置き換える。 コンストラクタのパラメータの数が他のメソッドよりも多いのはよくあることだ、 なんて言われるけれど、ここはDataClumpsが見つかるいい場所なのだ。

ContextualValidationと一緒に使うにはどうすればいいの?

ここでの文脈は、オブジェクトの基本的な使用である——つまり、使い物になる状態であればそれでよいのだ。 他の様々なアクティビティに使うには妥当でなくとも、 使い物になる程度には妥当であるべきだ。