#freeze [[リファクタリング]] * Factoryによるクラス群の隠蔽 [#tfab3f4f] ** 兆候 [#t1811a9c] 1つのパッケージ内にある共通のインタフェースを実装しているクラス群を、クライアントが直接インスタンス化 している。 &ref(before.jpg); ** 処置 [#r1532a33] クラスのコンストラクタをパブリックでなくし、クライアントにはFactory経由でインスタンスを生成させる。 &ref(after.jpg); ** 動機 [#m103db41] クライアントが直接クラスをインスタンス化できて役立つのは、それらのクラスの存在そのものを知る必要が ある場合だけである。 「共通インタフェースを実装したインスタンスを生成して返す」という責務をFactoryに持たせることで、クライアントからパッケージ内のクラスを隠蔽することができる。 これによって、 - クライアントが共通のインタフェースを通じてクラスとやりとりするようになる(インタフェースに対するプログラミング)。 - パッケージ外に公開する必要のないクラスが隠蔽され、パッケージの「概念的重み」を減らすことができる。 - Factoryに用意された意図の明確なCreation Methodを用いてインスタンスを生成することができる。 ** 手順 [#gf3cadcc] + ある種類のインスタンスを生成するために、クラスのコンストラクタを呼び出している箇所を探す。 -- [[メソッドの抽出>リファクタリング/メソッドの抽出]]をコンストラクタの呼び出し部分に適応し、パブリックなstaticメソッドを作成する。 -- [[メソッドの移動>リファクタリング/メソッドの移動]] を適用して、選択したコンストラクタを持つスーパークラスに生成メソッドを移動する。 + 生成メソッドと同じ種類のインスタンスを生成するために、先に選択したコンストラクタを呼び出している部分をすべて洗い出し、生成メソッドを呼び出すように変更する。 + クラスのコンストラクタが生成するインスタンスの種類毎に、ステップ1,2を繰り返す + クラスのコンストラクタをパブリック以外に変更する。 + カプセル化したいすべてのクラスについて、ステップ1〜4を繰り返す。 ** コメント [#d3d9ef06] ##comment_kcaptcha