web-dev-qa-db-fra.com

Conversion de nombreuses déclarations 'if else' en une approche plus propre

Mon code ici détecte si la mimeType est égale à un peu de MIME type, si c'est le cas, il fera une certaine conversion

public void convertToMp3(File src, File target,String mimeType){
    if(mimeType.equals("audio/mpeg")){
        ...
    }else if(mimeType.equals("audio/wav")){
        mp3ToWav();
    }else if(mimeType.equals("audio/ogg")){
        ...
    }else if(...){
    ... //More if and else here
}

J'ai raccourci mon code, car il contient beaucoup d'instructions else if. Quel modèle de conception convient à la suppression de nombreuses instructions if et else ou else if?

111
user962206

Vous pourriez avoir une interface Converter. Ensuite, vous pouvez créer une classe pour chaque type Mimet comme:

public interface Converter {

    public void convertToMp3();
    public void convertToOgg();

}

public class MpegConverter implements Converter {

    public void convertToMp3() {
        //Code here
    }

    public void convertToOgg() {
        //Code here
    }

}

Vous auriez besoin d'une classe comme celle-ci pour chaque convertisseur. Ensuite, vous pouvez configurer une carte comme celle-ci:

Map<String, Converter> mimeTypeMap = new HashMap<String, Converter>();

mimeTypeMap.put("audio/mpeg", new MpegConverter());

Alors votre méthode convertToMp3 devient comme ceci:

Converter converter = mimeTypeMap.get(mimeType);
converter.convertToMp3();

En utilisant cette approche, vous pourriez facilement ajouter différents convertisseurs dans le futur.

Tous non testés, ne compile probablement pas, mais vous avez l'idée

192
cowls

Si vous utilisez une version antérieure à JDK7, vous pouvez ajouter une énumération pour tous les types MIME :

  public static enum MimeTypes {
      MP3, WAV, OGG
  }

  public class Stuff {
      ...
      switch (MimeTypes.valueOf(mimeType)) {
          case MP3: handleMP3(); break;
          case WAV: handleWAV(); break;
          case OGG: handleOGG(); break;
      }
  }

Et jetez un coup d'oeil à la question de débordement de pile Java - Convertir une chaîne en enum sur la conversion des chaînes en enum.

23
pgras

Pensez à utiliser le modèle de conception de la stratégie et une variable Map pour les envoyer à la stratégie appropriée. Particulièrement utile si vous avez besoin de fonctionnalités supplémentaires, en plus d’une conversion pour une mimeType particulière, ou si les convertisseurs sont un code volumineux et complexe et que vous souhaitez placer chaque convertisseur dans son propre fichier .Java.

 interface Convertor {
    void convert(File src, File target);
 }

 private static void convertWav(File src, File target) {
    ...
 }

 ...

 private static final Map< String, Convertor > convertors = new ...;
 static {
    convertors.put("audio/wav", new Convertor {
       void convert(File src, File target) {
          convertWav(src, target);
       }
    });
    convertors.put("audio/ogg", new Convertor {
       void convert(File src, File target) {
          convertOgg(src, target);
       }
    });
    ...
 }

 public void convertToMp3(File src, File target, String mimeType){
     final Convertor convertor = convertors.get(mimeType);
     if (convertor == null ) {
        ...
     } else {
        convertor.convert(src, target);
     }
 }
15
Raedwald

Si vous exécutez le mêmes méthodes pour chaque cas, vous devriez vérifier Modèle d'état

3
Marcin Szymczak

C'est vraiment un modèle de conception de stratégie. Mais vous avez un gros problème dans votre conception générale. Utiliser String pour identifier un type n'est pas une habitude de programmation. Tout simplement parce que c'est facilement modifiable et que vous pouvez faire une erreur de grammaire et passer tout l'après-midi à la recherche d'une erreur de programmation. Vous pouvez éviter d'utiliser la carte <>.

Je suggère ce qui suit:

  1. Étendre le fichier de classe. La nouvelle classe ajoute un nouvel attribut FileType et une nouvelle méthode convertTo (FileType) à la classe File. Cet attribut conserve son type: "audio", "wav" ... et n'utilisez pas encore String, Use Enum. Dans ce cas, je l'ai appelé FileType. Extension de fichier autant que vous le souhaitez: WavFile, AudioFile ...
  2. Utilisez une stratégie pour créer vos convertisseurs.
  3. Utilisez un dp d’usine pour initialiser les convertisseurs.
  4. Puisque chaque fichier connaît son propre type et le type de cible (utilisez la méthode convertTo () pour spécifier le type de cible), il appellera l'usine pour obtenir automatiquement le convertisseur correct !!!

Cette conception est évolutive et vous pouvez ajouter autant que vous avez besoin de FileType et de convertisseurs.

2
george

Si vous utilisez JDK 7, vous pouvez utiliser switch-case construct:

Voir: Pourquoi ne puis-je pas activer une chaîne?

if-else est le seul choix possible pour les versions précédentes.

2
Azodious

Si vous n'utilisez pas Java 7, vous pouvez créer une enum et utiliser cette valeur avec un cas switch. Il suffit ensuite de passer la valeur enum (plutôt qu’un fichier, je ne comprends pas pourquoi vous le faites). Cela aurait l'air plus propre aussi.

Ceux-ci devraient aider avec ce que vous voulez faire:

 [Java Enum Examples][1] - 
 [Java Switch Case examples][2]
0
Skepi