導入
ビンゴゲームも盛り上がってきた頃、
というわけで、
展開
BingoProgression
クラスを継承する
BingoProgression
クラスは一方通行にビンゴ数列の要素を吐き出します。吐き出したあとは、BingoMachine
アプリケーションを再起動すると、
例えばこのスクリーンショットは、
このような外見で、
これを作業とします。そして作業については条件があります。
BingoProgression
クラスを継承すること。BingoProgression
クラスを継承したRewindableBingoProgression
クラスを作成してください。このクラスに、数列の最初の要素から再度数列を取得するための goHead
メソッドを持たせてください。BingoProgression
クラスのソースコードには一切手を加えないこと。理不尽ですが、
作業の課題ですからそのようにしてください。現実的な状況を想定するならば、 BingoProgression
クラスのソースが公開されていない場合や契約上コードの変更が許されない場合だとしてください。
また、集合の要素の最初に戻る機能付きのIteratorインタフェイスを連載第24回で作ったようにRewindableBingoProgression
クラスに実装しても良いのですが、
リプレイ機能付きで親切なビンゴマシンのコード
作業により、
BingoProgression
クラスを継承しましたから、BingoProgression
クラス側で行われます。サブクラスであるRewindableBingoProgression
クラスにはビンゴ数列生成のコードはありません。
これは継承を利用する際のありがたさです。サブクラス側にcreateBingoProgression
というコードが全くなくても、
継承の弊害
さて、
例えば、RewindableBingoProgression
クラスは、Iterator
インタフェイスのメソッドを利用しています。その際、
絶対に継承を利用したほうがわかりやすい、
では、
そこでリファクタリング
委譲による継承の置き換え
継承によって生まれるコードの読みにくさを解消するには、
委譲による継承の置き換え
(Replace Inheritance with Delegation) サブクラスがスーパークラスの一部の機能しか利用しないのに継承を利用していたり、
そもそもクラス同士の関係として継承が不適切な場合がある。この時継承を取りやめて委譲を用いたコードに書き換える。
Replace Inheritance with Delegation
今回は、
具体的には、RewindableBingoProgression
クラスが持つ機能は先の作業で作成した時と同じにします。BingoProgression
クラスの機能を利用すること、goHead
メソッドを持つことなどです。ただし、RewindableBingoProgression
クラスはIterator
インターフェイスを実装し、BingoProgression
の持つすべてのメソッドのシグニチャを持ち、
では、BingoProgression
クラスと同じコードを持つ必要があるのでしょうか。それはあまりにも無駄な仕事です。そこで、
RewindableBingoProgression
クラスのオブジェクトが生成される際、BingoProgression
のオブジェクトを生成し、RewindableBingoProgression
クラスのローカルオブジェクトとして保持させます。そして、BingoProgression
オブジェクトからビンゴ数列を吸い出して、RewindableBingoProgression
オブジェクトで利用します。ビンゴ数列の生成をBingoProgression
クラスのオブジェクトに委譲するのです。大まかなコードにすれば次のとおりです。
その他の部分は、RewindableBingoProgression
クラスと同様です。今回のような例であれば、
コードには大差ありませんから、
「継承」の役割・意味
継承はオブジェクト指向プログラミング言語の特徴的な機能です。基本となるクラスを拡大
演習
演習1(難易度:very easy)
BingoMachine.
にリファクタリングRewindableBingoProgression
クラスを書き換えましょう。リファクタリングの前後でアプリケーションの振る舞いに違いを生じさせないでください。
まとめ
- リファクタリング
「委譲による継承の置き換え」 を学習しました。
学習の確認
それぞれの項目で、
- 「委譲による継承の置き換え」
の意図と効果が理解できましたか? - 理解できた。
- 意図は理解できたが、
効果を感じない。 - 理解できない。
参考文献
- 『新装版 リファクタリング―既存のコードを安全に改善する―
(OBJECT TECHNOLOGY SERIES)』(マーチン・ ファウラー 著、 オーム社) - かつてピアソン・
エデュケーション社から出版されていたものの新装版です。リファクタリングのバイブルですから、 必携です。
- かつてピアソン・
- 『Java言語で学ぶリファクタリング入門』
(結城浩 著、 ソフトバンククリエイティブ) - ファウラーのバイブルと併せて読むことをお勧め。著者の解説は一級です。
- 『エクストリームプログラミング』
(ケント・ ベック、 シンシア・ アンドレス 著、 オーム社) - エクストリームプログラミングの原典。本連載をここまで学習された方はぜひとも読んでみてください。
演習解答
- リファクタリングを施したコードを次に示します。