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

MediaPlayerWrapper次に、 a の代わりに aを使用するだけですMediaPlayer

于 2014-12-13T04:28:27.633 に答える
0

解決策は、有名な FACTORY パターンを使用してリファクタリングすることです。

ファクトリ パターンとは、要するに、入力に基づいてクラスを動的にロードする作成パターンです。クライアントは、実装またはサブクラスに関する情報をまったく持っていません。

あなたの場合、上に投稿したコードはクライアントであり、理想的にはサブクラスを認識しないでください。むしろ、クライアントに目的のサブクラスを提供する責任を負う 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 に答える