![](/img/trans.png)
[英]How can i instantiate a different subclass based on common identifier (java)
[英]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.