如何在不同的情况下使用不同的子类?

时间:2014-12-13 04:23:56

标签: java design-patterns media-player decouple

我有这样的困境:

我有父类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
}

我是否有更好的选择来重构代码以减少耦合?

2 个答案:

答案 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

你可能看起来很圆,但是想法是客户端不应该知道子类及其松散耦合,使代码更加模块化。希望这能回答你的问题。