引き続き7章読んでいく。
7章
メソッドやフィールドをどのオブジェクトに管理させるかは、オブジェクトの設計でもっとも重要な判断の一つである。
この問題に対応するためのテクニックについて学んだ。
メソッドの移動(Move Method)
メソッドが、自分のクラスの機能より他のクラスの機能を利用している場合は、そのメソッドがもっともよく使うクラスに新しいメソッドを作る。
クラスの機能が増え、2つのメソッドが密結合になりすぎたときは、メソッドの移動を行うことを考える。
フィールドの移動(Move Field)
メソッドの移動と同じような観点でフィールドが、自分のクラスより他のクラスからよく使われている場合は、そのクラスに新しいフィールドを作る。
クラスの抽出(Move Field)
クラスの仕事が1つではない場合は、新しいクラスを作って仕事を移す。
クラスは凝縮された抽象として少数の明確な任務を果たすべき
ちょっとした機能だと、既存クラスに追加してしまいがちだけど、本当にそのクラスで仕事させるべき機能なのかを考え、必要に応じて新しいクラスを作る必要がある。
クラスのインライン化(Inline Class)
クラスが大した仕事をしていない場合は、全ての機能を他のクラスに移してから消す。
クラスの抽出の逆 (サンプルのコード、結局戻すんかい)
移譲の隠蔽(Hide Delegate)
クライアントがオブジェクト内の委譲クラスを呼び出している場合、委譲を隠すためのメソッドを作りカプセル化する。 カプセル化とは、オブジェクトがシステムの他の部分についてあまり知識がないということ。
forwardableを使うことで、処理を移譲した機能を提供することができる。
横流しブローカーの除去(Remove Middle Man)
移譲の隠蔽でデメリットが出る場合に実施する。 移譲オブジェクトに追加するメンバが増えてくると苦痛になってくる。 その場合、クライアントが直接呼び出したほうがよい。
所感
6章は戦術的なリファクタで、各コードを読みやすく、保守しやすくするテクニックに対して7章はクラス設計に関わる部分。 これらを後から行うの結構きつそう。こういった手法は予め知っておくことで綺麗な設計を心がけることができそう。 また一つのテクニックを説明したあと、次でそれの逆を説明してくれている(「移譲の隠蔽」と「横流しブローカーの除去」など)ので、盲目的にカプセル化だ!とか思わず、こういうパターンもあるし、どっちにするか?と思考できるのがよい。