【Java言語で学ぶリファクタリング入門】クラスの抽出
いきさつ
昔書いたコードが悲しい感じだった&どこから手を付ければよいかわからない感じだったので、
リファクタリングの知識が欲しかった。
そしたら手元にこの本があった。
リファクタリング前
Playerクラス
class Player { private _currentMedia; private _musicData; private _videoData; public setMedia() { }; public play() { }; public loop() { }; public stop() { }; private playMusic() { }; private loopMusic() { }; private stopMusic() { }; private playVideo() { }; private loopVideo() { }; private stopVideo() { }; }
playerが責務を持ちすぎ。
- musicの再生・停止・ループ方法を知っている
- videoの再生・停止・ループ方法を知っている
なにがしんどいのか
新しいmediaを追加するたびにmethodを追加する必要がある。
playerが再生されるものに対しての知識を持ちすぎているので、密結合。
リファクタリング方法
クラスの抽出を行なう。
リファクタリング後
新たにMusicMediaとVideoMediaクラスを作った。
Mediaクラス
/** 共通インターフェース */ interface Playable { play(); loop(); stop(); } /**MusicMedia */ class MusicMedia implements Playable { public play() { }; public stop() { }; public loop() { }; } /** VideoMedia */ class VideoMedia implements Playable { public play() { }; public stop() { }; public loop() { }; }
Playerクラス
class Player { private _currentMedia: Playable; public setMedia(media: Playable) { this._currentMedia = media; } public play() { this._currentMedia.play(); } public stop() { this._currentMedia.stop(); } public loop() { this._currentMedia.loop(); } }
何がうれしいのか
新たにMediaを追加する時に、既存のコードに手を加えなくて良い(拡張に対して開いている)
既存のmediaの修正をする時に、クラス内で修正が収まる(修正に対して閉じている)
PlayerクラスはPlayableインターフェースを実装しているクラスなら何でも扱えるので、疎結合