我有这样的困境:
我有父类MediaPlayer
,然后一些子类从它延伸,假设它们是MediaPlayerSub1
MediaPlayerSub2
MediaPlayerSub3
,它们都扩展了一些不同的方法。
在我的客户端,我想在不同的情况下使用不同的子类,所以我遇到了困难:当我使用MediaPlayer
时,我总是需要判断它是哪个子类,例如:
MediaPlayer mMediaPlayer = initPlayer()
// ... do some operation from MediaPlayer
// ... do operation from sub class
if (mMediaPlayer instanceof MediaPlayerSub1) {
mMediaPlayer = (MediaPlayerSub1)mMediaPlayer;
// ... do operation from MediaPlayerSub1
} else if (mMediaPlayer instanceof MediaPlayerSub2) {
mMediaPlayer = (MediaPlayerSub2)mMediaPlayer;
// ... do operation from MediaPlayerSub2
} else if (mMediaPlayer instanceof MediaPlayerSub3) {
mMediaPlayer = (MediaPlayerSub3)mMediaPlayer;
// ... do operation from MediaPlayerSub3
}
我是否有更好的选择来重构代码以减少耦合?
答案 0 :(得分:1)
如果您是MediaPlayer的作者,您可以在MediaPlayer中编写一个抽象方法
abstract void action();
并在每个子类中覆盖它,如下所示:
@Override
void action() {
// do something
}
然后你只需要拨打mMediaPlayer.action()
。
如果您不是MediaPlayer的作者,您可以使用包装类执行相同的操作,例如
abstract class MediaPlayerWrapper {
private final MediaPlayer mediaPlayer;
MediaPlayerWrapper(MediaPlayer mediaPlayer) {
this.mediaPlayer = mediaPlayer;
}
MediaPlayer getMediaPlayer() {
return mediaPlayer;
}
abstract void action();
}
然后为MediaPlayer的每个子类创建子类。像这样:
final class MediaPlayerWrapper1 extends MediaPlayerWrapper {
MediaPlayerWrapper1(MediaPlayerSub1 mediaPlayer) {
super(mediaPlayer);
}
@Override
public void action() {
// do stuff with the MediaPlayer. You will need to call getMediaPlayer() first.
}
}
然后,您只需使用MediaPlayerWrapper
代替MediaPlayer
。
答案 1 :(得分:0)
解决方案是使用着名的FACTORY模式进行重构。
简而言之,工厂模式是一种创建模式,您可以根据输入动态加载类。客户端没有关于实现或子类的任何信息。
在您的情况下,您在上面发布的代码是客户端,理想情况下它不应该知道子类。相反,它应该知道Factory类负责为客户提供所需的子类。
public enum MediaType {
MEDIA1 ,MEDIA2 , MEDIA3, NULL ;
}
public class MediaFactory {
public static MediaPlayer getMediaInstance(MediaType mediaType) {
if( mediaType == MediaType.MEDIA1) return new MediaPlayerSub1(mediaType);
if( mediaType == MediaType.MEDIA2) return new MediaPlayerSub2(mediaType);
if( mediaType == MediaType.MEDIA3) return new MediaPlayerSub3(mediaType);
return new MediaPlayer();
}
}
// client code
MediaPlayer mediaPlayer = MediaFactory.getMediaInstance(MediaType.NULL);
MediaPlayer mediaPlayer = MediaFactory.getMediaInstance(MediaType.MEDIA1);
MediaPlayer mediaPlayer = MediaFactory.getMediaInstance(MediaType.MEDIA2);
MediaPlayer mediaPlayer = MediaFactory.getMediaInstance(MediaType.MEDIA3);
if (mediaPlayer.getMediaType() ==MediaType.MEDIA1) // do mediaSub1 operations
if (mediaPlayer.getMediaType() ==MediaType.MEDIA2) // do mediaSub2 operations
if (mediaPlayer.getMediaType() ==MediaType.MEDIA3) // do mediaSub3 operations
你可能看起来很圆,但是想法是客户端不应该知道子类及其松散耦合,使代码更加模块化。希望这能回答你的问题。