Javaのより良い書き方を指南する『Java言語で学ぶリファクタリング入門』(2/2)

結城浩Java言語で学ぶリファクタリング入門』を写経しつつ読み終わりました。

Java言語で学ぶリファクタリング入門

Java言語で学ぶリファクタリング入門

本書は全部で15章あり、大きく3つの内容に分かれています。

そのうち、本エントリーでは「クラスの関係を整える大規模なリファクタリング」を説明した第11章~第15章を扱います。

「コードを整える小規模なリファクタリング」「クラスを整える中規模なリファクタリング」を説明した第10章までを扱ったエントリーはこちら

対象読者

  • プログラミングを初めて日が浅い人
  • Javaでの開発・実行環境がある人

サンプルコードの処理内容はそれほど難しくないと思います。2つ目の条件の理由ですが、本書を有効活用するには、実際にコードを書くことが不可欠なためです。

クラスの隠蔽

第11章はFactory Methodを扱っていますが、本書でも重要な章だと思います。

クラス名がnewでハードコードされているのを、Factory Methodに置き換えるリファクタリングです。

このリファクタリングによって何ができるようになるかというと、呼び出し側*1が、Factory Methodでインスタンス生成を行うことで「実際に生成するクラスを実行時に定めることができ」ます。

本書でのリファクタリング後のコードを例にとります。呼び出し側(Main.java)で、図形のインスタンスを作成するコードは以下のようになっています。

Shape line = Shape.createLine(0, 0, 100, 200);
Shape rectangle = Shape.createRectangle(10, 20, 30, 40);
Shape oval = Shape.createOval(100, 200, 300, 400);

251ページから253ページを見ればわかるように、ここで作成されるインスタンスのクラスは、それぞれShapeのサブクラスであるShapeLine、ShapeRectangle、ShapeOvalとなっています。

しかし、呼び出し側ではそれらのクラス名は登場しない、すなわち隠蔽されています。

さて、第11章で重要なポイントは練習問題にもあります。

それはDependency Injectionです。呼び出し側でのインスタンスの生成時に依存関係を作り出す手法です。詳しくは練習問題の解答を参照してください。

DIについて、Spring入門書では、「開発者がFactory Methodなどのデザインパターンを駆使しなくても、DIコンテナから受け渡されるインスタンスをインタフェースで受け取れば、インタフェースベースのコンポーネント化が実現できる」と記載されています。

軽く調べた*2ところ、本書が出版されていた2007年当時ではSpring2.0が出ていたようです。

DIとFactory Methodが、似たような問題を解決するための手法であることを知れたのは、大きな収穫でした。

継承と委譲

第13章から第15章では、継承と委譲についてのリファクタリングが説明されていて、方針としては継承をやめて委譲を用いています。

Effective Javaでは継承について、スーパークラスの変更にサブクラスが影響されてしまうから使うときは注意すべきという指摘をしています。

個人的な感覚としては、Is-a関係があまり成り立ってなさそうだけど継承を使ってしまった、という経験はあまりないような気がします。

とはいえ、相続拒否に対しては良くない匂いを感じ取れるようになりたいですね。

これ以上先に進もうとすると、Javaにおける設計についてより深く学ぶ必要がありそうです。

まとめ

文法を知っている、実際に動くコードが書ける、より洗練されたコードが書けるという3ステップを考えたとき、本書では2つ目から3つ目のステップを学べると思います。

特に5章・6章・8章・11章が、個人的には重要に感じました。理由としては、出現頻度が高いことや、修正についての解説の有用性が高いことが挙げられます。

*1:本文中では「クライアント」と言われている

*2:参考→https://www.slideshare.net/movmov/spring-12-49833796