1

我有一个这样的困境:

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

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

4

2 回答 2

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.
    }
}

然后你只需要使用 aMediaPlayerWrapper而不是 a MediaPlayer

于 2014-12-13T04:28:27.633 回答
0

解决方案是使用著名的 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

您可能看起来有点绕,但想法是客户端不应该了解子类及其松散耦合,从而使代码更加模块化。希望这回答了你的问题。

于 2014-12-13T05:05:34.340 回答