[英]How can I use different subclass in different situation?
I have a dilemma like this: 我有这样的困境:
I have parent class MediaPlayer
, then some subclass extends from it, let's say they are MediaPlayerSub1
MediaPlayerSub2
MediaPlayerSub3
, all of they extend some differnt methods. 我有一个父类MediaPlayer
,然后从它继承了一些子类,假设它们是MediaPlayerSub1
MediaPlayerSub2
MediaPlayerSub3
,它们都扩展了一些不同的方法。
In my client, I want use different subclass in different situation, so I am faced with difficulties: when I use MediaPlayer
I always need to judge which subclass it is, for example: 在我的客户端中,我想在不同的情况下使用不同的子类,因此遇到了很多困难:当我使用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
}
Do I have better choice to refactor the code to reduce the coupling? 我是否有更好的选择来重构代码以减少耦合?
If you are the author of MediaPlayer you can just write an abstract method in MediaPlayer 如果您是MediaPlayer的作者,则可以在MediaPlayer中编写一个抽象方法
abstract void action();
and override it in each of the subclasses, like this: 并在每个子类中覆盖它,如下所示:
@Override
void action() {
// do something
}
Then you just need to call mMediaPlayer.action()
. 然后,您只需要调用mMediaPlayer.action()
。
If you are not the author of MediaPlayer you can do the same thing but using wrapper classes, like this 如果您不是MediaPlayer的作者,则可以执行相同的操作,但可以使用包装器类,如下所示
abstract class MediaPlayerWrapper {
private final MediaPlayer mediaPlayer;
MediaPlayerWrapper(MediaPlayer mediaPlayer) {
this.mediaPlayer = mediaPlayer;
}
MediaPlayer getMediaPlayer() {
return mediaPlayer;
}
abstract void action();
}
Then you create subclasses for each subclass of MediaPlayer. 然后,为MediaPlayer的每个子类创建子类。 Like this: 像这样:
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.
}
}
Then you just need to use a MediaPlayerWrapper
instead of a MediaPlayer
. 然后,您只需要使用MediaPlayerWrapper
而不是MediaPlayer
。
The solution is to refactor using famous FACTORY pattern. 解决方案是使用著名的FACTORY模式进行重构。
Factory pattern in short is a creational pattern where you dynamically load classes based on Input. 简而言之,工厂模式是一种创建模式,您可以在其中基于Input动态加载类。 The client has no information whatsoever on the implementation or sub classes. 客户端没有关于实现或子类的任何信息。
In your case , the code you posted above is client and ideally it should not be aware of subclasses. 在您的情况下,上面发布的代码是客户端,理想情况下,它应该不知道子类。 Rather it should be aware of a Factory class who is responsible to provide client with desired subclass. 而是应该知道有一个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
You might seem round about way, but idea is client should not know about subclasses and its kind of loose coupling, making code more modular. 您可能看起来很绕道,但是想法是客户不应该知道子类及其松散耦合的种类,从而使代码更具模块化。 Hope this answered your question. 希望这回答了您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.