Monday 21 December 2009

C++ リファクタリング

Java Kuche で既に勉強会のネタになっていたんですが、機能拡張するのに継承を使うとよろしくないという話。あんまりピンと来ないでスルーしてたんですが...

 SDLViwer extended viewer
 FBViwer extended viewer

とかになっていて、で、学生が viewer を拡張しようとするんだが...

 SgViewer is copied from viewer
 SgSDLViwer extended Sgviewer
 SgFBViwer extended SGviewer

ってなことに... だから、コピーすると、その後、変更をそのコピー全部に対して変更しないとだめになっちゃうんだよ... 学生はコピー大好きだからな〜

継承されてしまったクラスを元のソースを維持しながら拡張するのって、やっぱり難しい。

なので、まず、SDLViwer/FBViewer の依存性を見直して、

 viewer has a SDLViewer extended ViewerDevice
 viewer has a FBViewer extended ViewerDevice

ってな感じに書き直します。ここで、ViewerDevice が abstract class/interface/pure virtual class になって、前回のはまりに継ったわけなんだけど。

で、
 SgViewer extended viewer
とすると、viewer を作っているところとかを直さないといけないので、厳しい。そもそも、違うアルゴリズムの実装なので拡張じゃないし。

viewerの部品を利用するという形に近いんだよな。なので、こっちも、
 SgViewer has a viewer
にして、viewer の方の method を再利用可能 (インスタンス変数ではなくて、引数をで渡す) みたいな形に。

まぁ、だいたい動いたんだけど、最初の書き換えで「全部の例題を書き換える」という技が出ていたので、それを元に戻すとか、SgViewer が動いてないとかあるけど、それは、自分で直してよ。

でも、これで、SgViewer のコピーされたコードは消せたので、まぁ、良いかな。

コピー部分が多いコードは、拡張性/維持性とも問題あるんだけど、実際に拡張する立場にならないとわからないよね。

No comments: