将许多"if else"语句转换为更清晰的方法

use*_*206 111 java design-patterns

我的代码在这里检测是否mimeType等于某种MIME类型,如果是,它将进行某种转换

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
}
Run Code Online (Sandbox Code Playgroud)

我缩短了我的代码,因为它有很多其他if语句,什么设计模式适合删除许多ifelseif语句?

cow*_*wls 192

你可以有一个Converter界面.然后你可以为每个Mimetype创建一个类,如:

public interface Converter {

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

}

public class MpegConverter implements Converter {

    public void convertToMp3() {
        //Code here
    }

    public void convertToOgg() {
        //Code here
    }

}
Run Code Online (Sandbox Code Playgroud)

对于每个转换器,您都需要这样的类.然后你可以设置这样的地图:

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

mimeTypeMap.put("audio/mpeg", new MpegConverter());
Run Code Online (Sandbox Code Playgroud)

然后你的convertToMp3方法变成这样:

Converter converter = mimeTypeMap.get(mimeType);
converter.convertToMp3();
Run Code Online (Sandbox Code Playgroud)

使用这种方法,您可以在将来轻松添加不同的转换器.

所有未经测试的,可能都没有编译,但你明白了

  • 对于那些可能不知道的人,这被称为[战略模式](https://en.wikipedia.org/wiki/Strategy_pattern). (10认同)
  • 好主意,看起来对我来说是一个非常干净的解决方案.只是不要忘记检查是否确实存在处理程序并在没有找到处理程序时给出错误消息. (3认同)
  • 在此示例中,在MPEGConverter上使用convertToMp3方法将MPG转换为MP3,convertToOgg用于将MPG转换为OGG.所以不,他们没有做同样的工作.可能与命名混淆 (2认同)

pgr*_*ras 23

如果使用pre-JDK7,则可以为所有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;
      }
  }
Run Code Online (Sandbox Code Playgroud)

并查看Stack Overflow问题Java - 转换字符串以枚举如何将字符串转换为枚举.

  • 你为什么不把一个句柄方法放在枚举本身?那么它将是`MimeTypes.valueOf(mimeType).handle()`. (15认同)
  • 我无法相信这种反应建议使用`switch`作为重构多个`if else if`的方式得到23个upvotes.Grrr ......当我想到那里有什么样的开发者时,它让我很害怕. (3认同)

Rae*_*ald 15

考虑使用策略设计模式和a Map调度到适当的策略.如果你需要额外的功能,除了特定mimeType的转换,或转换器是大而复杂的代码,你会希望将每个转换器放在自己的.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);
     }
 }
Run Code Online (Sandbox Code Playgroud)