繁体   English   中英

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

[英]How can I use different subclass in different situation?

我有这样的困境:

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

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

如果您是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

解决方案是使用著名的FACTORY模式进行重构。

简而言之,工厂模式是一种创建模式,您可以在其中基于Input动态加载类。 客户端没有关于实现或子类的任何信息。

在您的情况下,上面发布的代码是客户端,理想情况下,它应该不知道子类。 而是应该知道有一个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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM