[英]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.